Godot-proposals: Requesting a new notification method that will be called when node is constructed and all child nodes are added to its tree

Created on 7 May 2020  路  7Comments  路  Source: godotengine/godot-proposals

Describe the project you are working on:
Simple 2D game.

Describe the problem or limitation you are having in your project:
Why there is no notification when all child nodes are added to parent node?
Maybe today I just don't understand something, but let's follow this use case.

For example I create scene (MyEntity) that has child node CollisionShape2D
var myEntity = MyEntity.instance()

myEntity has property bounding_box. That property should be calculated while constructing myEntity.
For that it should use radius of shape property of CollisionShape2D child node.

Currently that is not possible using _init method, because child nodes are not yet created when this notification is called so I cannot access them.
The _ready method cannot be used either, because myEntity is not yet added to tree.

Describe the feature / enhancement and how it helps to overcome the problem or limitation:
Currently the only possible way I can think of is to create custom method calculate_bounding_box in myEntity and call it right after creation of myEntity, like this:

    var myEntity = MyEntity.instance()
    myEntity.calculate_bounding_box()

calculate_bounding_box looks like this:

    func calculate_bounding_box():
        bounding_box = Rect2(
            -$CollisionShape2D.shape.radius,
            -$CollisionShape2D.shape.radius,
            $CollisionShape2D.shape.radius * 2,
            $CollisionShape2D.shape.radius * 2)

This method has already access to all child nodes.
Adding new notification method like _post_init or _children_entered_tree would fix that issue.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
Just method like other notification methods, called in correct order, when object is created and all children nodes are added to tree.

If this enhancement will not be used often, can it be worked around with a few lines of script?:
Described above.

Is there a reason why this should be core and not an add-on in the asset library?:
It should be standard notification method like _ready, _enter_tree and so on.

archived core

Most helpful comment

You can simply use the node_added() signal from SceneTree.
Basically doing something like:

func _ready():
  get_tree().connect("node_added", self, "my_func")

func my_func(node):
  if node == <thenodeyouwant>:
    #do your stuff

Notifications go through the whole tree even if not processed by all nodes. As it's an heavy processing, it's unlikely we are going to add a notification for that use case, as it can be easily worked around as I just showed.

All 7 comments

You could use the signal tree_entered in CollisionShape2D by calling the calculate_bounding_box () function from myEntity

Yes, this is another option, but still kind of workaround.

You can simply use the node_added() signal from SceneTree.
Basically doing something like:

func _ready():
  get_tree().connect("node_added", self, "my_func")

func my_func(node):
  if node == <thenodeyouwant>:
    #do your stuff

Notifications go through the whole tree even if not processed by all nodes. As it's an heavy processing, it's unlikely we are going to add a notification for that use case, as it can be easily worked around as I just showed.

@groud You have used _ready function, so how this is different than just accessing node directly with get_node()? _ready function may be not called at all if node is not added to scene tree.
Also get_tree() return null in _init method. So this is no solution for me.

Honestly your problem is quite hard to understand... You claim to need a signal to know when a node enter the tree, so I assumed your code was outside the node you added. In such case, you could perfectly use the parent's (which would be already in the tree) _ready() method.

If your node needs to know when it is added to the tree itself, then this is exactly what the _ready() function is doing (by being called when a node enters the tree).

If a node needs to know when a children is added to it, you can connect it to the SceneTree signal and verify when the node is added if the added one is one of its children (with something like added_node.get_parent == self) or even a grand child with self.is_a_parent_of(added_node).

I'm also having trouble understanding.

_init is the constructor method, _ready is used for when something is added to the tree with all of it's children which would be what you want isn't it?

Guys, I thought about this case and now I think that adding this notification is not so crucial as I thought at the beginning. So I will close this ticket.
Thank you for your time.

Was this page helpful?
0 / 5 - 0 ratings