mirror of
https://github.com/godotengine/godot.git
synced 2026-01-06 10:11:57 +03:00
Merge pull request #64487 from Rindbee/fix-instantiated-scene-duplicate
Fix resource shared when duplicating an instanced scene
This commit is contained in:
@@ -2953,10 +2953,11 @@ Node *Node::duplicate(int p_flags) const {
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap) const {
|
||||
return duplicate_from_editor(r_duplimap, HashMap<Ref<Resource>, Ref<Resource>>());
|
||||
HashMap<Node *, HashMap<Ref<Resource>, Ref<Resource>>> tmp;
|
||||
return duplicate_from_editor(r_duplimap, nullptr, tmp);
|
||||
}
|
||||
|
||||
Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const {
|
||||
Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, Node *p_scene_root, HashMap<Node *, HashMap<Ref<Resource>, Ref<Resource>>> &p_resource_remap) const {
|
||||
int flags = DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR;
|
||||
Node *dupe = _duplicate(flags, &r_duplimap);
|
||||
|
||||
@@ -2969,8 +2970,8 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, con
|
||||
_duplicate_properties(this, this, dupe, flags);
|
||||
|
||||
// This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated.
|
||||
if (!p_resource_remap.is_empty()) {
|
||||
remap_node_resources(dupe, p_resource_remap);
|
||||
if (p_scene_root) {
|
||||
remap_node_resources(dupe, p_scene_root, p_resource_remap);
|
||||
}
|
||||
|
||||
// Duplication of signals must happen after all the node descendants have been copied,
|
||||
@@ -2981,7 +2982,9 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, con
|
||||
return dupe;
|
||||
}
|
||||
|
||||
void Node::remap_node_resources(Node *p_node, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const {
|
||||
void Node::remap_node_resources(Node *p_node, Node *p_scene_root, HashMap<Node *, HashMap<Ref<Resource>, Ref<Resource>>> &p_resource_remap) const {
|
||||
Node *local_scene = p_node->is_instance() ? p_node : (p_node->get_owner() ? p_node->get_owner() : p_scene_root);
|
||||
|
||||
List<PropertyInfo> props;
|
||||
p_node->get_property_list(&props);
|
||||
|
||||
@@ -2991,23 +2994,39 @@ void Node::remap_node_resources(Node *p_node, const HashMap<Ref<Resource>, Ref<R
|
||||
}
|
||||
|
||||
Variant v = p_node->get(E.name);
|
||||
if (v.is_ref_counted()) {
|
||||
Ref<Resource> res = v;
|
||||
if (res.is_valid()) {
|
||||
if (p_resource_remap.has(res)) {
|
||||
p_node->set(E.name, p_resource_remap[res]);
|
||||
remap_nested_resources(res, p_resource_remap);
|
||||
}
|
||||
if (!v.is_ref_counted()) {
|
||||
continue;
|
||||
}
|
||||
Ref<Resource> res = v;
|
||||
if (res.is_null()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (res->is_local_to_scene()) {
|
||||
if (local_scene == res->get_local_scene()) {
|
||||
continue;
|
||||
}
|
||||
Ref<Resource> dup = SceneState::get_remap_resource(res, p_resource_remap, nullptr, local_scene);
|
||||
p_node->set(E.name, dup);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (res->is_built_in()) {
|
||||
// Use nullptr instead of a specific node (current scene root node) to represent the scene,
|
||||
// as the Make Scene Root operation may be executed.
|
||||
if (p_resource_remap[nullptr].has(res)) {
|
||||
p_node->set(E.name, p_resource_remap[nullptr][res]);
|
||||
remap_nested_resources(res, p_resource_remap[nullptr]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
remap_node_resources(p_node->get_child(i), p_resource_remap);
|
||||
remap_node_resources(p_node->get_child(i), p_scene_root, p_resource_remap);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::remap_nested_resources(Ref<Resource> p_resource, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const {
|
||||
void Node::remap_nested_resources(Ref<Resource> p_resource, HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const {
|
||||
List<PropertyInfo> props;
|
||||
p_resource->get_property_list(&props);
|
||||
|
||||
|
||||
@@ -721,9 +721,9 @@ public:
|
||||
Node *duplicate(int p_flags = DUPLICATE_GROUPS | DUPLICATE_SIGNALS | DUPLICATE_SCRIPTS) const;
|
||||
#ifdef TOOLS_ENABLED
|
||||
Node *duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap) const;
|
||||
Node *duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const;
|
||||
void remap_node_resources(Node *p_node, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const;
|
||||
void remap_nested_resources(Ref<Resource> p_resource, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const;
|
||||
Node *duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, Node *p_scene_root, HashMap<Node *, HashMap<Ref<Resource>, Ref<Resource>>> &p_resource_remap) const;
|
||||
void remap_node_resources(Node *p_node, Node *p_scene_root, HashMap<Node *, HashMap<Ref<Resource>, Ref<Resource>>> &p_resource_remap) const;
|
||||
void remap_nested_resources(Ref<Resource> p_resource, HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const;
|
||||
#endif
|
||||
|
||||
// used by editors, to save what has changed only
|
||||
|
||||
Reference in New Issue
Block a user