Set an instanced node's owner before it can call _ready

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

When instancing a node at runtime, is there a good way to set its owner before it has a chance to call _ready?

Some example code below:

#OwnerKnower.gd
class_name OwnerKnower
extends Node2D

func _ready():
    print("My name is %s and my owner is %s" % [name, owner.name])

#---#

#Game.gd
extends Node2D

func _input(event):
    if event.is_action_pressed("ui_accept"):
        var new_node = OwnerKnower.new()
        new_node.name = "NodeAddedInScript"
        new_node.owner = self 
        add_child(new_node)

With the _input in the order above, I get this error when trying to set the owner:

set_owner: Condition "!owner_valid" is true.

I presume this is because the owner is not an ancestor of the node, which makes sense since it’s not in the tree yet.

If I move the new_node.owner = self line after the add_child line, then _ready is called before I have a chance to set the owner, and so the owner is still null at that time.

I can work around this by passing the intended owner in a separate variable and having the node set its own owner in _ready, but it feels wrong:

#OwnerKnower.gd
class_name OwnerKnower
extends Node2D

var new_owner:Node = null

func _ready():
    if new_owner:
        owner = new_owner

    print("My name is %s and my owner is %s" % [name, owner.name])

#--#

#Game.gd
extends Node2D

func _input(event):
    if event.is_action_pressed("ui_accept"):
        var new_node = OwnerKnower.new()
        new_node.name = "NodeAddedInScript"
        new_node.new_owner = self
        add_child(new_node)

Hi,
have you tried to set the owner when the node emits tree_entered?

new_node.connect( "tree_entered", new_node, "set_owner", self);

klaas | 2021-09-11 11:56