Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | Ricardo Noriega | |
Old Version | Published before Godot 3 was released. |
I’m modifying an object’s position using set_pos()
(also tried set_global_pos()
) and a weird thing is happening.
The game I’m doing has random encounters and what I’m trying to do is put the player in the same position he was before the encounter. The way I’m doing it is that right before changing scenes to the battle area I save the player’s position to a singleton node and after coming back I set the player’s position to that saved position.
# return to overworld code
print("pos before set_pos(): ", player.get_global_pos())
player.set_global_pos(Stats._get_current_position())
print("pos after setting pos: ", player.get_global_pos())
# have tried this with set_pos() instead just in case but same behavior
This code indeed prints the position that the player is set to in the scene editor (200, 242) and then prints whatever position I was before the encounter (I always move near 0, 0 to test this and it does print the correct value) but the player in the game is positioned at (200, 242).
No clue how to tackle this. At first, I thought that maybe the player object was being created after changing the position but wouldn’t that give an error for trying to do set_pos()
on a null variable?
[EDIT]
I’m pretty sure I figured out why it isn’t working, but not how I can fix it. I’ll explain.
The way I have set up the project is that the main scene is a Node
called Game
. This node reads from a file which scene (level/area/map, call it what you want) has to be instanced, and instances it. These scenes all have a Player Overworld
Node2D
instanced in the scene editor.
The way I change scenes is that I delete all of Game
’s children with a for loop and then instantiate the target scene. The reason I’m not using change_scene()
or change_scene_to()
is because doing so makes the Game
object disappear. So because they way I’ve set it up is that the Game
Node
is always there, I can’t use those functions and had to come up with another way. And here is (very likely) the problem:
for child in get_children():
child.queue_free()
Since I’m using queue_free()
, the player
variable gotten from _get_player_overworld()
isn’t the one in the new scene, but the one on the previous scene, still in the queue waiting to be freed. If I use free()
Godot itself doesn’t give any type of error, but Windows does give the “A problem caused the program to stop working correctly.” prompt.
I could probably solve this with a few flags but that’s not really a solution. I guess the follow-up/relevant question is how to replace a Node’s children rather than the whole scene, which is what change_scene()
and change_scene_to()
do.
did you make player
instance from script?
or is the player
node in scene tree in editor?
volzhs | 2017-02-22 15:54
Player Overworld
is a node in the scene editor assigned to the player
variable in script like this:
player = _get_player_overworld()
func _get_player(): # get the player node
var p = get_tree().get_nodes_in_group("Player Overworld")
return p[0]
Where the Player Overworld
node is part of “Player Overworld” group. There are probably better ways to find it, but this works as intended. If player has a variable var test = 5
I can do
player = _get_player_overworld()
print(player.test)
succesfully.
Ricardo Noriega | 2017-02-22 16:03