Merge pull request #112076 from kevinlam508/custom-node-reference-duplication

Fix duplicating node references of custom node type properties
This commit is contained in:
Thaddeus Crews
2025-11-11 16:07:53 -06:00
2 changed files with 23 additions and 7 deletions

View File

@ -2932,6 +2932,10 @@ Node *Node::duplicate(int p_flags) const {
ERR_FAIL_NULL_V_MSG(dupe, nullptr, "Failed to duplicate node.");
if (p_flags & DUPLICATE_SCRIPTS) {
_duplicate_scripts(this, dupe);
}
_duplicate_properties(this, this, dupe, p_flags);
if (p_flags & DUPLICATE_SIGNALS) {
@ -2952,6 +2956,10 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, con
ERR_FAIL_NULL_V_MSG(dupe, nullptr, "Failed to duplicate node.");
if (flags & DUPLICATE_SCRIPTS) {
_duplicate_scripts(this, dupe);
}
_duplicate_properties(this, this, dupe, flags);
// This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated.
@ -3024,6 +3032,20 @@ void Node::_emit_editor_state_changed() {
}
#endif
void Node::_duplicate_scripts(const Node *p_original, Node *p_copy) const {
bool is_valid = false;
Variant scr = p_original->get(CoreStringName(script), &is_valid);
if (is_valid) {
p_copy->set(CoreStringName(script), scr);
}
for (int i = 0; i < p_original->get_child_count(false); i++) {
Node *copy_child = p_copy->get_child(i, false);
ERR_FAIL_NULL_MSG(copy_child, "Child node disappeared while duplicating.");
_duplicate_scripts(p_original->get_child(i, false), copy_child);
}
}
// Duplicate node's properties.
// This has to be called after nodes have been duplicated since there might be properties
// of type Node that can be updated properly only if duplicated node tree is complete.
@ -3031,13 +3053,6 @@ void Node::_duplicate_properties(const Node *p_root, const Node *p_original, Nod
List<PropertyInfo> props;
p_original->get_property_list(&props);
const StringName &script_property_name = CoreStringName(script);
if (p_flags & DUPLICATE_SCRIPTS) {
bool is_valid = false;
Variant scr = p_original->get(script_property_name, &is_valid);
if (is_valid) {
p_copy->set(script_property_name, scr);
}
}
for (const PropertyInfo &E : props) {
if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
continue;

View File

@ -315,6 +315,7 @@ private:
void _propagate_translation_domain_dirty();
Array _get_node_and_resource(const NodePath &p_path);
void _duplicate_scripts(const Node *p_original, Node *p_copy) const;
void _duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const;
void _duplicate_signals(const Node *p_original, Node *p_copy) const;
Node *_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap = nullptr) const;