@@ -2737,25 +2737,9 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c
27372737 }
27382738
27392739 } else {
2740- // If property points to a node which is owned by a node we are duplicating, update its path.
2741- if (value.get_type () == Variant::OBJECT) {
2742- Node *property_node = Object::cast_to<Node>(value);
2743- if (property_node && is_ancestor_of (property_node)) {
2744- value = current_node->get_node_or_null (get_path_to (property_node));
2745- }
2746- } else if (value.get_type () == Variant::ARRAY) {
2747- Array arr = value;
2748- if (arr.get_typed_builtin () == Variant::OBJECT) {
2749- for (int i = 0 ; i < arr.size (); i++) {
2750- Node *property_node = Object::cast_to<Node>(arr[i]);
2751- if (property_node && is_ancestor_of (property_node)) {
2752- arr[i] = current_node->get_node_or_null (get_path_to (property_node));
2753- }
2754- }
2755- value = arr;
2756- }
2740+ if (value.get_type () != Variant::OBJECT && (value.get_type () != Variant::ARRAY || static_cast <Array>(value).get_typed_builtin () != Variant::OBJECT)) {
2741+ current_node->set (name, value);
27572742 }
2758- current_node->set (name, value);
27592743 }
27602744 }
27612745 }
@@ -2771,6 +2755,8 @@ Node *Node::duplicate(int p_flags) const {
27712755 _duplicate_signals (this , dupe);
27722756 }
27732757
2758+ _duplicate_properties_node (this , this , dupe);
2759+
27742760 return dupe;
27752761}
27762762
@@ -2792,6 +2778,8 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, con
27922778 // if the emitter node comes later in tree order than the receiver
27932779 _duplicate_signals (this , dupe);
27942780
2781+ _duplicate_properties_node (this , this , dupe);
2782+
27952783 return dupe;
27962784}
27972785
@@ -2844,6 +2832,44 @@ void Node::remap_nested_resources(Ref<Resource> p_resource, const HashMap<Ref<Re
28442832}
28452833#endif
28462834
2835+ // Duplicates properties that store a Node.
2836+ // This has to be called after nodes have been duplicated since
2837+ // only then do we get a full picture of how the duplicated node tree looks like.
2838+ void Node::_duplicate_properties_node (const Node *p_root, const Node *p_original, Node *p_copy) const {
2839+ List<PropertyInfo> props;
2840+ p_copy->get_property_list (&props);
2841+ for (const PropertyInfo &E : props) {
2842+ if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
2843+ continue ;
2844+ }
2845+ String name = E.name ;
2846+ Variant value = p_original->get (name).duplicate (true );
2847+ if (value.get_type () == Variant::OBJECT) {
2848+ Node *property_node = Object::cast_to<Node>(value);
2849+ if (property_node && (p_root == property_node || p_root->is_ancestor_of (property_node))) {
2850+ value = p_copy->get_node_or_null (p_original->get_path_to (property_node));
2851+ p_copy->set (name, value);
2852+ }
2853+ } else if (value.get_type () == Variant::ARRAY) {
2854+ Array arr = value;
2855+ if (arr.get_typed_builtin () == Variant::OBJECT) {
2856+ for (int i = 0 ; i < arr.size (); i++) {
2857+ Node *property_node = Object::cast_to<Node>(arr[i]);
2858+ if (property_node && (p_root == property_node || p_root->is_ancestor_of (property_node))) {
2859+ arr[i] = p_copy->get_node_or_null (p_original->get_path_to (property_node));
2860+ }
2861+ }
2862+ value = arr;
2863+ p_copy->set (name, value);
2864+ }
2865+ }
2866+ }
2867+
2868+ for (int i = 0 ; i < p_copy->get_child_count (); i++) {
2869+ _duplicate_properties_node (p_root, p_original->get_child (i), p_copy->get_child (i));
2870+ }
2871+ }
2872+
28472873// Duplication of signals must happen after all the node descendants have been copied,
28482874// because re-targeting of connections from some descendant to another is not possible
28492875// if the emitter node comes later in tree order than the receiver
0 commit comments