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
};