Enemy always moves left, even when player is on the right

Godot Version

4.4.1

Question

My mob moves only in one direction, even when the player is on the other side. Here is my code:

extends CharacterBody2D

var chase = false
var speed = 100
func _physics_process(delta: float) -> void:
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta
	var player = 	$"../../Player"
	var direction = (player.position - self.position).normalized()	
	if chase == true:
		velocity.x = direction.x * speed
	else:
		velocity.x = 0	
	move_and_slide()			
		

func _on_area_2d_body_entered(body: Node2D) -> void:
	if body.name == "Player":
		chase = true
func _on_area_2d_body_exited(body: Node2D) -> void:
	if body.name == "Player":
		chase = false

You are comparing local positions, maybe you would have better results using global_position for both the player and your enemy.

2 Likes

Maybe another solution would be to compare position.x and then set a direction independently based on whoever has highest. Or use a raycast on each side.
If you want to use your solution, i would try adding print statements here and there to try to figure out exactly where things go wrong.

Maybe try:
var direction = sign(player.position.x - self.position.x)
velocity.x = direction * speed

1 Like

To add to the recommendations, you can use position.direction_to() and position.distance_to() for a cleaner implementation. Refer to the Vector2 docs for more useful methods:

1 Like

A unique name would allow you to use $%Player directly and not have assign it to the local player var.

Additionally, you can save some cpu time by this:

func _physics_process(delta: float) -> void:
	# Add the gravity
	if not is_on_floor():
		velocity += get_gravity() * delta
	else: # small logic change here: only change the x velocity if on the ground
  		velocity.x = 0
		if chase == true:
			velocity.x = ($%Player.global_position - self.global_position).normalized() * speed
	move_and_slide()	

To expand a little on @gertkeno correct answer: position is always in relation to the parent node. If your Character2D in inside say a Node2D that you name Enemy then the position is most likely 0,0 unless you accidentally moved it, while the global_position is a very different value and what anyone would understand as position on the screen when running the game.
Sadly there’s not much in the official tutorial to get this difference across.

1 Like