diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index c9c94eff36ea..dd182f82454b 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -1137,6 +1137,9 @@ Duplicate using instancing. An instance stays linked to the original so when the original changes, the instance changes too. + + Duplicate the node's references, changing all exported [Node] properties to be part of the newly duplicated hierarchy, if possible. Does not work without [constant DUPLICATE_USE_INSTANTIATION]. + Node will not be internal. diff --git a/scene/main/node.cpp b/scene/main/node.cpp index d8a50c4313a1..3a8f0777808b 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2523,6 +2523,18 @@ Node *Node::_duplicate(int p_flags, HashMap *r_duplimap) c Variant value = N->get()->get(name).duplicate(true); + if (p_flags & DUPLICATE_NODE_REFERENCES && + E.type == Variant::OBJECT && + ClassDB::is_parent_class(E.class_name, SNAME("Node"))) { + Node *node_from_property = Object::cast_to(value); + if (node_from_property) { + NodePath relative_path = get_path_to(node_from_property); + + current_node->set(name, node->get_node(relative_path)); + continue; + } + } + if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) { Resource *res = Object::cast_to(value); if (res) { // Duplicate only if it's a resource @@ -3466,6 +3478,7 @@ void Node::_bind_methods() { BIND_ENUM_CONSTANT(DUPLICATE_GROUPS); BIND_ENUM_CONSTANT(DUPLICATE_SCRIPTS); BIND_ENUM_CONSTANT(DUPLICATE_USE_INSTANTIATION); + BIND_ENUM_CONSTANT(DUPLICATE_NODE_REFERENCES); BIND_ENUM_CONSTANT(INTERNAL_MODE_DISABLED); BIND_ENUM_CONSTANT(INTERNAL_MODE_FRONT); diff --git a/scene/main/node.h b/scene/main/node.h index feda200b24b2..05c36311b46d 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -91,8 +91,9 @@ class Node : public Object { DUPLICATE_GROUPS = 2, DUPLICATE_SCRIPTS = 4, DUPLICATE_USE_INSTANTIATION = 8, + DUPLICATE_NODE_REFERENCES = 16, #ifdef TOOLS_ENABLED - DUPLICATE_FROM_EDITOR = 16, + DUPLICATE_FROM_EDITOR = 32, #endif };