Reputation:
I'd like to access the root node of a scene, but even in its _ready()
lifecycle method I get a runtime error telling the parent node is busy:
extends Node2D
func _ready():
self.get_tree().get_root().add_child(preload("res://MainMenu.tscn").instance())
# This works:
# self.get_tree().change_scene("res://MainMenu.tscn")
My current script is just changing scene for now. I know I can use this [object NodeTree].change_scene()
method or root_node.call_deferred()
, but I'd like to be able to observe to when the scene is fully initialized, so I can freely use its node tree.
Upvotes: 2
Views: 1230
Reputation: 40295
At the time _ready
runs, the parent node is not ready yet (let alone the scene root). Godot has not finished the routine that add children to the parent node. In fact, it just added your current node, the children of your current node, and is running _ready
on your current node. After it has done that for your current node and its siblings, it will run _ready
on your parent node, and so on, until it reaches the scene root… Then it will be ready.
Lightning_A is correct, inserting yield(get_tree().get_root(), "ready")
before manipulating the root will work. yield
will halt the execution and schedule it to continue after the given signal. The ready
signal in this case. Which happens after _ready
completed.
This is how you would use it:
func _ready():
yield(get_tree().get_root(), "ready")
get_tree().get_root().add_child(preload("res://MainMenu.tscn").instance())
Another common solution is to insert yield(get_tree(), "idle_frame")
instead. The signal idle_frame
happens just before Godot calls _process
:
func _ready():
yield(get_tree(), "idle_frame")
get_tree().get_root().add_child(preload("res://MainMenu.tscn").instance())
Upvotes: 2
Reputation: 340
Does Node
's ready
signal work for you? i.e. yield(get_tree().get_root(), "ready")
Upvotes: 1