2

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?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
fguillen
  • 36,125
  • 23
  • 149
  • 210

3 Answers3

2

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:

  • 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 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).
  • 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.

Theraot
  • 31,890
  • 5
  • 57
  • 86
2

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

0

Not sure your use case,

but in godot 4, I use await to check node is ready:

func for_setup():
    # do things
    await the_wait_node.ready

it will wait to the node emit ready signal, which is mentioned in your link.

some resource: https://gdscript.com/solutions/coroutines-and-yield/

XMRHRX
  • 33
  • 8