How to fix enemy sprite not fliping when loaded from a preload

Godot Version

4.2.2

Question

I have a problem with my enemy’s sprite not flipping. It worked before but now whn I try loading the enemy from a object (Like a enemy spawner) it doesn’t work.

My enemy’s code:

extends CharacterBody2D

var receives_knockback: bool = true
var knockback_modifier: float = 3
var knockback_velocity := Vector2.ZERO
var ACCELERATION = 1500
var FRICTION = 60000
var SPEED = 800.0
var SPEEDLESS = 200.0
var SPEEDLESSes = 100.0
var loopy = 3
var goofy = 1
var othergoofy = 0
var stop = true
var dizzy = 0
var motion = false
var breaking = false
var motionstart = false
var motionend = false
var death = false
var idle = true
var deathcounter = 4
var hit = false
@onready var rollyaway = $ROLLY
# Get the gravity from the project settings to be synced with RigidBody nodes.
@onready var player = get_parent().get_parent().get_parent().get_node("Player")
@onready var playerpos = global_position.direction_to(player.global_position)
@onready var rng = RandomNumberGenerator.new()
@onready var my_random_number = rng.randf_range(1, 100)


func _process(delta):
	
	pass


func _physics_process(delta):
	if(player.position.x - position.x) > 0:
		$Sprite2D.flip_h = true
	elif(player.position.x - position.x) < 0:
		$Sprite2D.flip_h = false
	if knockback_velocity.is_zero_approx() == false:
		velocity = knockback_velocity
		move_and_slide()
		knockback_velocity = Vector2.ZERO
		return

	velocity = velocity.move_toward(Vector2.ZERO, 200 * delta)
	move_and_slide()
	if hit == true:
		$AnimationPlayer.play("flash")
		await get_tree().create_timer(0.8).timeout
		hit = false
	if deathcounter == 0:
		death = true
	if death == true:
		queue_free()
	
	move_and_slide()
	if motion == true and motionend == false and idle == false:
		$AnimationPlayer.play("rollrollypoly")
	elif motionstart == true and idle == false:
		$AnimationPlayer.play("startrollypoly")
	elif motionend == true and idle == false:
		$AnimationPlayer.play("endrollypoly")
	elif breaking == true and idle == false:
		$AnimationPlayer.play("dizzyrollypoly")

	elif idle == true and motionstart == false:
		

		$AnimationPlayer.play("idlerollypoly")
	if rollyaway.is_colliding():
		velocity += rollyaway.get_pushed() * 60000
	if stop == false:
		$Area2D.monitoring = true
		$Area2D.monitorable = true
		playerpos = global_position.direction_to(player.global_position)
		velocity.x += (playerpos.x * SPEED) * delta
		velocity.y += (playerpos.y * SPEED) * delta
		await get_tree().create_timer(2).timeout
		
		
		motion = false
		
		motionend = true
		await get_tree().create_timer(0.45).timeout
		motionend = false
		stop = true
	else:
		$Area2D.monitoring = false
		$Area2D.monitorable = false
		playerpos = global_position.direction_to(player.global_position)
		velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)
		idle = true
		
		
		await get_tree().create_timer(2).timeout
		idle = false
		motionstart = true
		await get_tree().create_timer(0.50).timeout
		motion = true
		stop = false
		motionstart = false


func receive_knockback(damage_source_pos: Vector2):
	if receives_knockback:
		var knockback_direction = damage_source_pos.direction_to(self.global_position)
		var knockback_strength = knockback_modifier * 100
		knockback_velocity = knockback_direction * knockback_strength


func _on_hurtbox_area_entered(area):
	if area.is_in_group("Slash") and stop == true:
		deathcounter -= 1
		hit = true
		receive_knockback(area.global_position)
	pass # Replace with function body.

My Spawner’s Code:

extends RigidBody2D
var cooldown = true
var ball_speed = Vector2(200,200) 
@onready var rolly = preload("res://Rollypoly.tscn")
func _process(delta):
	
	
	
	pass
func _physics_process(delta):
	##var collision_info = move_and_collide(ball_speed * delta)
	##if collision_info:
		##ball_speed = ball_speed.bounce(collision_info.get_normal())
	pass

func _on_timer_timeout():
	cooldown = false
	if cooldown == false:
		var r = rolly.instantiate()
		r.position = $Marker.position
		add_child(r)
		cooldown = true
	pass # Replace with function body.

Any help would be apperciated!

The enemy sprite flips depending on its relative position to the player, but the path to the player node is hardcoded as

get_parent().get_parent().get_parent().get_node("Player")

So my guess would be that this path is no longer correct when you add the enemy node as a direct child of the spawner. You should get errors from this, though.

The enemy mechanics and animations are working fine and is still spawning from the spawner, it just that the sprite wont flip horizontally.

And my point is that there’s only one place in your code that does that flipping, so those lines are either not called at all or at the wrong time. And since there’s only one condition that decides if these lines are run, the error must be there!

Is the spawner a direct child of your player? If not, it won’t work. If it is, then your enemies x-position is somehow equal to the player’s x-position.

I found out the issue, the sprite could flip but something was off center.

if(position.x - player.position.x) < 950: # number
		$Sprite2D.flip_h = true
	else:
		$Sprite2D.flip_h = false

I don’t know how to get it to re-center, but I’ll keep trying.

It would really help to know how your scene tree looks like and what the position values for all involved nodes (i.e. player, spawner, marker) are.

Enemy’s Sprite Position Info:
Screenshot_2024_06_11-4

Enemy’s Position Info:
Screenshot_2024_06_11-5

Enemy’s Spawner Position Info:
Screenshot_2024_06_11-6

Scene tree:


Rolly poly scene: