Clone of player mimicking player's movement. which shouldn't happen

Godot Version

Godot Version 4.4

Details

so I am making a 2d game. Player have an ability to clone themsleve. but the problem strike that The clone that is added is mimicking player's movement both walk and jumpping. The clone is actually whole another scene that is familiar to player but a little bit diffrent and I'm very sure I didn't add movement script to the clone.

Main Question

So how Do I fix this. to make the clone stop mimicking the player's movement

The player’s script

extends CharacterBody2D

@export var speed: float = 300.0  # Movement speed
@export var jump_force: float = 500.0  # Jump strength
@export var gravity: float = 1000.0  # Gravity strength

@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
var current_color: String = "Black"  # Default color is Black
var Cooldown = false

func _ready() -> void:
	var color_manager = CubeAbilitiesAutoload
	var Ability_manager = CubeAbilitiesAutoload
	color_manager.color_changed.connect(_on_color_changed)
	Ability_manager.connect("orange_ability_activated", Callable(self, "_on_Orange_Ability"))
	Ability_manager.connect("black_ability_activated", Callable(self, "_on_Black_Ability"))
	Ability_manager.connect("purple_ability_activated", Callable(self, "_on_Purple_Ability"))
	Ability_manager.connect("green_ability_activated", Callable(self, "_on_Green_Ability"))
	
func _physics_process(delta: float) -> void:
	# Apply gravity
	velocity.y += gravity * delta

	# Handle movement input
	var direction: int = get_movement_direction()
	handle_movement(direction)

	# Handle jumping
	if Input.is_action_just_pressed("Jump") and is_on_floor():
		SoundsAutoload.play_sound(SoundsAutoload.Jump, 10)
		velocity.y = -jump_force
		
	move_and_slide()

func get_movement_direction() -> int:
	var direction: int = 0
	if Input.is_action_pressed("Move_left") and not Input.is_action_pressed("Move_right"):
		direction = -1
	elif Input.is_action_pressed("Move_right") and not Input.is_action_pressed("Move_left"):
		direction = 1
	return direction

func handle_movement(direction: int) -> void:
	if direction != 0:
		velocity.x = direction * speed
		sprite.flip_h = (direction == -1)
	else:
		velocity.x = 0

	if is_on_floor():
		sprite.flip_v = false
		if direction != 0:
			sprite.play("Walk " + current_color)
		else:
			sprite.play("Idle " + current_color)
	else:
		if velocity.y < 0:
			sprite.play("Jump " + ("Side " if direction != 0 else "") + current_color)
		else:
			sprite.flip_v = true

func _on_color_changed(new_color: String) -> void:
	current_color = new_color

func _on_Orange_Ability():
	if Cooldown:
		return
	Cooldown = true
	velocity.y = -200
	_clone_scene_below_player()
	await get_tree().create_timer(4.0).timeout
	Cooldown = false

func _on_Black_Ability():
	pass

func _on_Purple_Ability():
	pass

func _on_Green_Ability():
	pass
	

var current_instance: Node2D = null

func _clone_scene_below_player() -> void:
	# Check if there's an existing instance and remove it
	if current_instance and is_instance_valid(current_instance):
		current_instance.queue_free()
		await current_instance.tree_exited  # Ensure the node is fully removed
	var scene = load("res://cube_clone.tscn")
	current_instance = scene.instantiate()
	current_instance.owner = get_tree().edited_scene_root
	current_instance.position = Vector2(0, 30)
	await get_tree().create_timer(0.2).timeout
	add_child(current_instance)

The clone’s script

extends CharacterBody2D

@export var gravity: float = 1000.0  # Gravity strength

@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
var push = false
var direction = 0

func _process(delta: float) -> void:
	if push:
		velocity.x = direction * 600 
	else:
		velocity.x = 0

func _physics_process(delta: float) -> void:

	# Apply gravity
	if not is_on_floor():
		velocity.y += gravity * delta

	if velocity.x != 0:
		sprite.flip_h = (velocity.x < 0)

	# Handle animations
	if is_on_floor():
		sprite.flip_v = false
		if abs(velocity.x) > 0:
			sprite.play("Walk")
		else:
			sprite.play("Idle")
	else:
		if velocity.y < 0:
			sprite.play("Jump")
		else:
			sprite.flip_v = true

	move_and_slide()

func _on_r_ight_body_entered(body: Node2D) -> void:
	if body.is_in_group("Player"):
		direction = -1
		push = true

func _on_left_body_entered(body: Node2D) -> void:
	if body.is_in_group("Player"):
		direction = 1
		push = true

func _on_r_ight_body_exited(body: Node2D) -> void:
	if body.is_in_group("Player"):
		direction = 0
		push = false

func _on_left_body_exited(body: Node2D) -> void:
	if body.is_in_group("Player"):
		direction = 0
		push = false

Could you show the clone’s scene tree?

1 Like

here is the picture

And what script does the clone have?

1 Like

My guess is that you mistakenly attached the player script to the clone script. That’s the only explanation I can think of.

1 Like

You likely cloned the same player script for the clone scene, they are both the “local” players and/or they both respond to the same keyboard inputs.

1 Like

The clone’s script


@export var gravity: float = 1000.0  # Gravity strength

@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
var push = false
var direction = 0

func _process(delta: float) -> void:
	if push:
		velocity.x = direction * 600 
	else:
		velocity.x = 0

func _physics_process(delta: float) -> void:

	# Apply gravity
	if not is_on_floor():
		velocity.y += gravity * delta

	if velocity.x != 0:
		sprite.flip_h = (velocity.x < 0)

	# Handle animations
	if is_on_floor():
		sprite.flip_v = false
		if abs(velocity.x) > 0:
			sprite.play("Walk")
		else:
			sprite.play("Idle")
	else:
		if velocity.y < 0:
			sprite.play("Jump")
		else:
			sprite.flip_v = true

	move_and_slide()

func _on_r_ight_body_entered(body: Node2D) -> void:
	if body.is_in_group("Player"):
		direction = -1
		push = true

func _on_left_body_entered(body: Node2D) -> void:
	if body.is_in_group("Player"):
		direction = 1
		push = true

func _on_r_ight_body_exited(body: Node2D) -> void:
	if body.is_in_group("Player"):
		direction = 0
		push = false

func _on_left_body_exited(body: Node2D) -> void:
	if body.is_in_group("Player"):
		direction = 0
                push = true

I have recheck and no, the script that is attached to the clone is correct.
The script that is attached to both player and clone is diffrent.

1 Like

At first I did cloned the player’s scene as for making the clone.
But I did cleared up most of things.

  1. they are both the “local” players I’m not sure about this one and don’t really know about this. how is it effecting it?
  2. and/or they both respond to the same keyboard inputs. I don’t think the clone would respond to it because I already cleared up all things related to Inputs inside the clone script. But if there is some possible way that my clone scene does respond to inputs, I wouldn’t know if it is happening.

Oh, I found out that the problem maybe wasn’t on the clone scene after all.
I tried to place the clone right away instead of using ability to add the clone.
it seems like the clone will only mimick player’s movement only when it is added to the scene by the function that is inside of player’s script.

So there’s two function where it mainly wrote for the spawn clone ability

func _on_Orange_Ability():
	if Cooldown:
		return
	Cooldown = true
	velocity.y = -200
	_clone_scene_below_player()
	await get_tree().create_timer(4.0).timeout
	Cooldown = false

func _clone_scene_below_player() -> void:
	# Check if there's an existing instance and remove it
	if current_instance and is_instance_valid(current_instance):
		current_instance.queue_free()
		await current_instance.tree_exited  # Ensure the node is fully removed
	var scene = load("res://cube_clone.tscn")
	current_instance = scene.instantiate()
	current_instance.owner = get_tree().edited_scene_root
	current_instance.position = Vector2(0, 30)
	await get_tree().create_timer(0.2).timeout
	add_child(current_instance)

You are making the clone a child of the player, so I think it is moving with it for that reason.

2 Likes

Ohh, You’re correct.
I tried change add_child(current_instance) into get_tree().current_scene.add_child(current_instance)
The clone stop moving when I tested. so now it’s all fine I guess?

the clone position was weird because this " current_instance.position = Vector2(0, 30) " wouldn’t work now but I fixed that using global position.

Thanks you all a lot for helpping me out! :green_heart: