Skip to content

Commit b9cc82d

Browse files
committed
Fix duplicating node references of custom node type properties
Script assignment must be complete for the subtree in order to correctly assign into properties set to a script type.
1 parent ab6c6ee commit b9cc82d

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

scene/main/node.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2951,6 +2951,10 @@ Node *Node::duplicate(int p_flags) const {
29512951

29522952
ERR_FAIL_NULL_V_MSG(dupe, nullptr, "Failed to duplicate node.");
29532953

2954+
if (p_flags & DUPLICATE_SCRIPTS) {
2955+
_duplicate_scripts(this, dupe);
2956+
}
2957+
29542958
_duplicate_properties(this, this, dupe, p_flags);
29552959

29562960
if (p_flags & DUPLICATE_SIGNALS) {
@@ -2971,6 +2975,10 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, con
29712975

29722976
ERR_FAIL_NULL_V_MSG(dupe, nullptr, "Failed to duplicate node.");
29732977

2978+
if (flags & DUPLICATE_SCRIPTS) {
2979+
_duplicate_scripts(this, dupe);
2980+
}
2981+
29742982
_duplicate_properties(this, this, dupe, flags);
29752983

29762984
// This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated.
@@ -3043,20 +3051,27 @@ void Node::_emit_editor_state_changed() {
30433051
}
30443052
#endif
30453053

3054+
void Node::_duplicate_scripts(const Node *p_original, Node *p_copy) const {
3055+
bool is_valid = false;
3056+
Variant scr = p_original->get(CoreStringName(script), &is_valid);
3057+
if (is_valid) {
3058+
p_copy->set(CoreStringName(script), scr);
3059+
}
3060+
3061+
for (int i = 0; i < p_original->get_child_count(false); i++) {
3062+
Node *copy_child = p_copy->get_child(i, false);
3063+
ERR_FAIL_NULL_MSG(copy_child, "Child node disappeared while duplicating.");
3064+
_duplicate_scripts(p_original->get_child(i, false), copy_child);
3065+
}
3066+
}
3067+
30463068
// Duplicate node's properties.
30473069
// This has to be called after nodes have been duplicated since there might be properties
30483070
// of type Node that can be updated properly only if duplicated node tree is complete.
30493071
void Node::_duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const {
30503072
List<PropertyInfo> props;
30513073
p_original->get_property_list(&props);
30523074
const StringName &script_property_name = CoreStringName(script);
3053-
if (p_flags & DUPLICATE_SCRIPTS) {
3054-
bool is_valid = false;
3055-
Variant scr = p_original->get(script_property_name, &is_valid);
3056-
if (is_valid) {
3057-
p_copy->set(script_property_name, scr);
3058-
}
3059-
}
30603075
for (const PropertyInfo &E : props) {
30613076
if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
30623077
continue;

scene/main/node.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ class Node : public Object {
315315
void _propagate_translation_domain_dirty();
316316
Array _get_node_and_resource(const NodePath &p_path);
317317

318+
void _duplicate_scripts(const Node *p_original, Node *p_copy) const;
318319
void _duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const;
319320
void _duplicate_signals(const Node *p_original, Node *p_copy) const;
320321
Node *_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap = nullptr) const;

0 commit comments

Comments
 (0)