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
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:
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.