Overriding add_child for instanced scene

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

I have a custom scene that I’ve built as a reusable dialog. I want any nodes added to an instance of that scene to be added to a descendant of the scene instead of the scene root. I have been able to get this partially working by overriding add_child in the scene’s script:

extends Control
@tool

func add_child(child: Node, force_readable_name: bool = false, internal: int = 0):
  get_node("./button_container").add_child(child, force_readable_name, internal)
  child.set_owner(self)

Any nodes added via the editor do show up in the scene preview, and if I enable “Editable Children” for the instanced scene I can see the new node in the tree (with a white label - all of the default nodes are in yellow). Once I save and reload the scene, the child node disappears. That says to me that the node isn’t being placed into the tree properly, so it’s not being serialized when I save the scene. I thought this may be due to the node’s owner not being set correctly, but setting the child’s owner to button_container or self doesn’t change anything.

The dream state would be to have the children of button_container listed in the scene tree editor as the children of the instanced scene.

:bust_in_silhouette: Reply From: spaceyjase

You’re correct, the node here won’t persist because add_child doesn’t do this:

Rather, you want to use node.set_owner(get_tree().edited_scene_root).

Along with this change, I found that I also have to enable “Editable Children” for the new nodes to be saved. Disabling “Editable Children” causes any nodes added to the instance to be removed (which the editor does warn you of).

I found that I could make this slightly easier on myself with the following (in the script on the root of the instanced scene):

func _ready():
  get_tree().edited_scene_root.set_editable_instance(self, true)
  self.set_display_folded(true)

This enables “Editable Children” automatically when I add a new instance to another scene, but also collapses its children to reduce clutter. It’s not perfectly ideal (I can still see all of the other nodes in the instanced scene when I expand the tree), but it will have to do.

Sunlis | 2023-01-22 05:47