The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

+6 votes

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

in Engine by (196 points)

2 Answers

+15 votes

_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: https://docs.godotengine.org/en/stable/getting_started/workflow/best_practices/godot_notifications.html#ready-vs-enter-tree-vs-notification-parented

I hope I helped you.

by (97 points)

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

+1 vote

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
by (52 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.