Why does the add_child() method change position?

This is my shoot function:
(I used a Node2D for a shooting point as suggested in a thread)

func shoot():
	var rocket_instance = rocket_scene.instantiate()
	rocket_instance.global_position = shooting_point.global_position
	print(global_position)
	print(shooting_point.global_position)
	print(rocket_instance.global_position)

	add_child(rocket_instance, true)

	print(global_position)
	print(shooting_point.global_position)
	print(rocket_instance.global_position)

This is the console result:

global pos
(564.1352, 342.0016)
shooting point pos
(611.1352, 342.0016)
rocket_instance pos
(611.1352, 342.0016)


global pos
(564.1352, 342.0016)
shooting point pos
(611.1352, 342.0016)
rocket_instance pos
(1175.27, 684.0033)

As you can see rocket_instance.global_position changed after I added the child.
Can you explain why the add_child() method will change the instance’s position?

If I use add_child() first then change the position with rocket_instance.global_position = shooting_point.global_position it works as I intended

I think the rocket_instance’s position is different because the add_child() will add the player’s location on top of the shooting_point.global_position .

I found this thread in the next course:
https://community.gamedev.tv/t/why-does-the-order-of-adding-child-and-setting-position-matter/232905

According to this if I set the global position before adding the child it won’t matter, because:

its not part of the scene tree at that point, and doesnt have any transform information

But clearly it does something, if I would remove the

rocket_instance.global_position = shooting_point.global_position

line, the rocket would spawn from the center of the player node

That’s the idea. Because everything is based in Node2Ds, the rocket will inherit the transform of its parent and it becomes an offset. I don’t remember offhand if this still happens when the rocket has Top Level ticked in its Inspector, but the problem is still fixed easily enough either way.

This is exactly why I consider it a best practice to place your add_child() line immediately after your instantiate() line.

I agree, as you’ve clearly shown. Don’t get me wrong, Shape definitely has the right idea, I think things just got lost in translation a little. All the other properties of a node exist at that point and can be modified before add_child(), so it’s less that the transform doesn’t exist and more that it’s easily overwritten unintentionally if you do it that way.

You’re writing excellent topics; keep it up =)

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms