Hello,

I am writing a tool script that creates an object whose class inherits Node.

This object can have multiple children (whose class also inherits Node), and it's possible for the user to select one of them in the editor, and delete it.

As there's no notification for deletion in the editor, I'm using NOTIFICATION_UNPARENTED. But this notification is also called when the scene is closed.

I need a way to check whether the child object was deleted specifically by the user, or simply unparented (along with all its siblings) because of the closure of the scene.

Assuming that children are removed according to their index inside the parent (that is: index 0, then 1, then 2, etc.), I'm considering adding a new, empty child at index 0 inside the parent, and checking if this child still exists when one of the others is unparented.

Are children deleted in order of index? Is this reliable behaviour? I think I vaguely remember reading something to this effect, but looking through the docs has not cleared things up.

Thank you.

  • cybereality Hello, and thank you for the response.

    Unfortunately, like you said, both child_exiting_tree() and tree_exiting() (in the child nodes) are called when the scene is closed, similarly to NOTIFICATION_UNPARENTED.

    Those additional checks you mention are the real problem, as the editor just doesn't seem to distinguish between a scene change and direct object removal by the user.

    Additionally, it seems I was completely wrong about the removal order of children, and they are actually removed in reversed index order: bottom to top.

    However, through testing, I found out a few things about removal order:

    1. All NOTIFICATION_EXIT_TREE events, for all objects, are sent out before any NOTIFICATION_UNPARENTED events.

    2. While child objects all receive the NOTIFICATION_EXIT_TREE event before the parent does, the opposite is true for NOTIFICATION_UNPARENTED: the parent receives it first.

    So, when the child receives its NOTIFICATION_UNPARENTED event, I can check if the parent is still inside the scene tree with get_parent().is_inside_tree(). If it is, then the scene is not being closed.

    This is encouraging, and probably good enough. But the Node page doesn't confirm this behaviour, so it does bring me back to my initial question: is this reliable?

Look on the signals for Node. I believe child_exiting_tree(child) on the parent node would be a good place to check what's happening. tree_exiting is also an interesting place. These happen usually on deletion, but can also happen if a tree branch is closed (like if you have a scene open in the editor and close it). So you'll have to do some additional checks to see that it was actually deleted.

https://docs.godotengine.org/en/stable/classes/class_node.html#signals

  • Nose replied to this.

    cybereality Hello, and thank you for the response.

    Unfortunately, like you said, both child_exiting_tree() and tree_exiting() (in the child nodes) are called when the scene is closed, similarly to NOTIFICATION_UNPARENTED.

    Those additional checks you mention are the real problem, as the editor just doesn't seem to distinguish between a scene change and direct object removal by the user.

    Additionally, it seems I was completely wrong about the removal order of children, and they are actually removed in reversed index order: bottom to top.

    However, through testing, I found out a few things about removal order:

    1. All NOTIFICATION_EXIT_TREE events, for all objects, are sent out before any NOTIFICATION_UNPARENTED events.

    2. While child objects all receive the NOTIFICATION_EXIT_TREE event before the parent does, the opposite is true for NOTIFICATION_UNPARENTED: the parent receives it first.

    So, when the child receives its NOTIFICATION_UNPARENTED event, I can check if the parent is still inside the scene tree with get_parent().is_inside_tree(). If it is, then the scene is not being closed.

    This is encouraging, and probably good enough. But the Node page doesn't confirm this behaviour, so it does bring me back to my initial question: is this reliable?

    Yes, the order of the nodes is reliable. I think checking if the parent is in the tree is probably enough.

    • Nose replied to this.

      You should have is_editor_hint to work with but beyond that nothing really.

      Well there's one thing I can think of. Just handle all the cases as 'scene closes' except for if the node/chain has been specifically reparented to a designated parent that is only supposed to hold nodes designated for deletion.

      OK two: You could also have a group dedicated for deletions I guess and tag things appropriately.

      • Nose replied to this.

        cybereality

        It's a little concerning that I can't find a primary source that formally states that a node is unparented before its children. But as long as it works, I suppose; thank you.

        Megalomaniak

        Re-parenting child nodes before removing them from the scene might work, but I think that would require me to intercept user input and... override the Del key? I don't know if that's even possible. Even if it is, it's a rather involved solution.

        Still, it may be worth considering for similar problems in the future; thank you.