Player.global_position isn't being set properly

Godot Version

4.2.2

Question

I’m making a 2D platformer/metroidvania where when they player dies they respawn at the last campfire they rested at (ala Dark Souls, I know, very original). I’ve written these two functions into my “World” script (which all of my levels inherit from):

func _on_player_rested():
Events.player_respawn_room = get_tree().current_scene.scene_file_path
Events.player_respawn_position = campfire.global_position
print(str(Events.player_respawn_room) + ", " + str(Events.player_respawn_position))

func _on_player_died():
get_tree().change_scene_to_file.bind(Events.player_respawn_room).call_deferred()
player.global_position = Events.player_respawn_position
print(str(player.global_position))

(Apologies if the code doesn’t format properly, this is my first time posting on the forum).

The first function is connected to a signal that the campfire sends when the player interacts with it, and sets the current level and the global position of the campfire as the player’s respawn point in a singleton. The second function is connected to a signal that the player sends when they die, and is supposed to load the respawn room and move the player to the respawn position. It loads the scene just fine, but always puts the player in their default position in the scene. What makes me feel like I’m going crazy is that the console literally prints the player’s global position as where it’s supposed to be, but it’s not! Why is Godot lying to me, and how can I make it stop?

I would guess changing the scene puts the player to it’s default position?
And because you call this line deferred, it will be called after you set the player’s global_position and printed it.

edit: You can connect signals to be called deferred, so the whole _on_player_died() function would be called deferred instead of just that one line, I think that would fix it.

1 Like

Yeah, I figured out that it’s because that code executes before changing the scene, so when the scene changes the player gets moved to their default position. I fixed it by moving the code to move the player to the _ready() function in an if statement.

1 Like