What is, if there is, signals of a new child added to a parent?

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

I reparanted a node and I want it to get signals from a new parent. So, I want a parent to make disconnects/connects. I wonder if there is a way for a parent to know if it has a new child so the parent do something.

By the way: how to reparent a node effectively.

:bust_in_silhouette: Reply From: PunchablePlushie

You can try using notifications to know if a node has a new child. If you don’t know what notifications are, here’s a brief intro on notifications.


The NOTIFICATION_PARENTED notification is received when a node gets parented, that is, when its parent gets changed.
So having something like this on the child would notify you whenever you reparent it:

func _notification(what):
    if what == NOTIFICATION_PARENTED:
        # Code here

If you specifically want the parent to know if it has a new child, you can try combining that notification with a custom signal defined on the parent.
So on the parent:

func _init():
    add_user_signal("got_new_child", [{"name": "child", "type": TYPE_OBJECT}])

And on the child:

func _notification(what):
    if what == NOTIFICATION_PARENTED:
        if get_parent().has_user_signal("got_new_child"):
            get_parent().emit_signal("got_new_child", self)

The two code blocks above make it so that the parent emits a signal anytime a new child is added to its children. You can easily connect this signal to any node you want, including the parent itself (using self). Note that this only works for the children that have that _notification() code block.

Also, the reason why we have to use add_user_signal() instead of just signal got_new_child is because the has_user_signal() method only works if you add your custom signal using the add_user_signal() method.
If you’re 100% sure that your child is always going to get a parent that has the got_new_child signal, you can completely skip the whole has_user_signal() check and just emit the signal right away. Then on the parent, you can just define the signal normally: signal got_new_child(child)


Finally, I don’t think there’s a built-in method for reparenting a node. But you can easily make your own:

func reparent_node(node, old_parent, new_parent):
    old_parent.remove_child(node)
    new_parent.add_child(node)
    node.owner = new_parent