Disclaimer: new in Godot here. Some experience with Unity
I am doing the initialization of my scripts into the _ready() method.
But I am missing a method that is automatically called on each script after all the _ready() methods have finished for all the Nodes in the scene. I understand that this is when all the tree has been loaded.
The reason is that in the _ready() method I initialize the actual script's internal state. But if I need to make some initialization, adjustments, and setup, into the scripts referenced by this one I need to be sure I do them after the _ready() method has finished on all that objects.
I see that this is the lifecycle of scripts in Godot:
This is the same in Unity:
As I am understanding the Godot's _ready() is equivalent to the Awake() in Unity.
I am missing in Godot what would be the equivalent of Start() in Unity. Which is called after all the objects have been initialized.
Does this method exist? Is there a workaround?
Godot calls the _ready method after it has called the _ready for all the children Nodes. 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 Nodes 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:
"ready" signal happens after it has already called the _ready method."ready" signal it won't send it again (unless the Nodes - 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).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.
You can do your initialization in a function called do_setup and then call this function deferred in the next frame by doing: call_deferred("do_setup")
If you do this in _ready the next frame will be the first frame of the game.
Like so:
func _ready():
call_deferred("do_setup")
func do_setup():
# Do initialization here
Docs: https://docs.godotengine.org/en/stable/classes/class_object.html#class-object-method-call-deferred
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With