Godot calls the _ready
method after it has called the _ready
for all the children Node
s. Thus, a first solution is to do your post-initialization on the _ready
of the scene root. I'll get back to this below.
When I say scene root, I mean the Node
that is the root of the scene where your Node
is (i.e. it's owner
)
On the other hand, when the Node
s are first instantiated Godot will call _init
. Which always happens before _ready
, but the Node
won't be in the scene tree, so if your initialization requires to access the scene tree that is not useful…
If you need to access the scene tree, consider using _enter_tree
. Godot will call _enter_tree
when it adds the Node
to the scene tree, which first happens before _ready
. Note that if you remove it and add it again, Godot will call _enter_tree
again.
I would argue that _init
is closer to Unity's Awake
or Reset
, and _ready
is the Start
you want. Perhaps you should be using _init
or _enter_tree
for your initialization. Or perhaps the _ready
you need is not the one on your Node
…
If you need the _ready
of the scene root (i.e. the owner
of your Node
), but you don't want to put your initialization code on the scene root, you can connect to it. Something like this:
func _ready() -> void:
owner.connect("ready", self, "_on_scene_ready")
func _on_scene_ready() -> void:
print("the scene is ready")
Notes and caveats:
- Godot sends the
"ready"
signal happens after it has already called the _ready
method.
- If Godot sent the
"ready"
signal it won't send it again (unless the Node
s - i.e. the root of the scene - is removed from the scene tree, ready is requested, and then it is added to the scene tree again).
- The presented code stops at scene boundaries. I'll get back to that.
- Because of the prior point, this connection is also possible form the editor.
As I said above, when I say scene root, I mean the Node
that is the root of the scene where your Node
is (i.e. it's owner
)… What if you want the current scene (the one you change with get_tree().change_scene(…)
)? Well, you can get it with get_tree().current_scene
so you can do this:
func _ready() -> void:
get_tree().current_scene.connect("ready", self, "_on_scene_ready")
func _on_scene_ready() -> void:
print("the scene is ready")
You could also do it with the root
of the whole scene tree get_tree().root
, which is the parent of the current scene and whatever you have autoloaded. I don't know how useful that would be. Yet be aware that the root
of the scene tree does not change, so it would be once per game execution.