functions _init or ready

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By lalel345

when should i use _init function?
what is the difference with respect to ready?

:bust_in_silhouette: Reply From: ra45

_init is more for class initialisation and it is called when the class is created, but _ready is called when the node is ready, that means when its children are ready.
You can find more information right here: Godot notifications — Godot Engine (stable) documentation in English

I hope I helped you.

you can pretty much just use the _ready() function all the time.

Millard | 2020-10-25 21:18

:bust_in_silhouette: Reply From: angstyloop

Indeed the docs say that you should have access to children and their properties in _ready. However this is not always the case, especially if you are creating new nodes dynamically by instancing scenes and adding them to your existing nodes, instead of having everything statically defined.

As a result, a lot of times you will try to access a property like “position” of a child node from within a parent node’s script (e.g. in the parent node’s _process function), and you will get errors like ‘bad index “position” on null thing’. This can happen in the _ready function. How do we wait on stuff to load asynchronously that isn’t available when _ready is called?

Here is one approach you can use.

You can connect the “tree_entered” signal on the child node to a method on the ancestor node.

If you are interested in children of the child node, you might want to use the “childenteredtree” signal instead. Or you could connect directly to the “tree_entered” signal on the lower child.

In your ancestor node, which presumably needs to make a function call like getnode(“MyChildNode”) or getnode(“MyChildNode/MyLowerChildNode”), and which is presumably causing issues and throwing errors like “bad index on null thing”, you can define a “ready” boolean variable initialized to “false”. All your “treeentered” or “childentered_tree” signal handlers (defined in the ancestor Node’s script) is set “ready” equal to “true”.

Then in your function that actually needs to call getnode and use the child’s data and methods, before you use the child you first check if “treeready” is true. If “tree_ready” is still false, you just skip the logic that messes with the node. You try to design your application in a such a way that it doesn’t care when things get loaded.

# MyAncestorNode.gd

extends Node2D

var child_node_ready = false
var lower_child_node_ready = false

func _process(delta):
    if ! child_node_ready:
        return
    print($MyChildNode.position)
    if ! lower_child_node_ready:
        return
    print($MyChildNode/MyLowerChildNode.position)

func _on_MyChildNode_child_entered_tree():
    lower_child_node_ready = true

func _on_MyChildNode_tree_entered():
    child_node_ready = true
1 Like