How to add a Camera to parent node?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By OnSr

Scene hierarchy:

-Spatial
—Spatial (with script)

√ Camera working:

extends Spatial

func _ready():
	var camerra = Camera.new()
	add_child(camerra)

× Camera not working:

extends Spatial

func _ready():
	var camerra = Camera.new()
	get_parent().add_child(camerra)

If I add the Camera node in the node itself, it moves, rotates, scales with the inner Spatial, that does not work for my use case. I need the camera to have the same parent as the child node. However, when I run the second code, I get a gray screen while the first code does what it should.

Strange :confused: try print(camerra.get_path()) or print(get_parent().get_path()) before calling add_child(). If nothing is printed you might have to use yield(get_tree(),"idle_frame") before calling anything else.

Magso | 2020-06-19 15:47

Thank you very much. Strangely yield(get_tree(),“idle_frame”) solves the problem. I though _ready was already called after idle_frame was emitted.

I think we might need to open an issue about this.

OnSr | 2020-06-19 20:27

:bust_in_silhouette: Reply From: OnSr

This is how I solved it. I hope it does not cost much performance.

extends Spatial

var camerra
var isCameraOn = false

func _ready():
	camerra = Camera.new()
	add_child(camerra)

func _physics_process(delta):
	if !isCameraOn:
		remove_child(camerra)
		get_parent().add_child(camerra)
		isCameraOn = true

yield() commented by @Magso also works. Maybe it works even better than this. I just wanted to let know this is what I am using.

Update:
Turns out there is an error which I did not notice before. There is also an advice in the Debugger.

add_child: Parent node is busy setting up children, add_node() failed. Consider using call_deferred("add_child", child) instead.

So, the working code I am currently using is:

extends Spatial

var camerra
var isCameraOn = false

func _ready():
	camerra = Camera.new()
	get_parent().call_deferred("add_child", (camerra))