user5066707
user5066707

Reputation:

How to defer custom action in scene startup?

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

Answers (2)

Theraot
Theraot

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

Aaron Record
Aaron Record

Reputation: 340

Does Node's ready signal work for you? i.e. yield(get_tree().get_root(), "ready")

Upvotes: 1

Related Questions