瀏覽代碼

Merge pull request #13288 from RandomShaper/fix-dup-crash

Fix crash on node duplication
Rémi Verschelde 7 年之前
父節點
當前提交
45d1f9a690
共有 1 個文件被更改,包括 9 次插入3 次删除
  1. 9 3
      scene/main/node.cpp

+ 9 - 3
scene/main/node.cpp

@@ -2114,8 +2114,16 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
 	node_tree.push_front(this);
 	node_tree.push_front(this);
 
 
 	if (instanced) {
 	if (instanced) {
+		// Since nodes in the instanced hierarchy won't be duplicated explicitly, we need to make an inventory
+		// of all the nodes in the tree of the instanced scene in order to transfer the values of the properties
+
 		for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
 		for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
 			for (int i = 0; i < N->get()->get_child_count(); ++i) {
 			for (int i = 0; i < N->get()->get_child_count(); ++i) {
+
+				// Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later
+				if (get_child(i)->data.owner != this)
+					continue;
+
 				node_tree.push_back(N->get()->get_child(i));
 				node_tree.push_back(N->get()->get_child(i));
 			}
 			}
 		}
 		}
@@ -2124,6 +2132,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
 	for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
 	for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
 
 
 		Node *current_node = node->get_node(get_path_to(N->get()));
 		Node *current_node = node->get_node(get_path_to(N->get()));
+		ERR_CONTINUE(!current_node);
 
 
 		if (p_flags & DUPLICATE_SCRIPTS) {
 		if (p_flags & DUPLICATE_SCRIPTS) {
 			bool is_valid = false;
 			bool is_valid = false;
@@ -2136,9 +2145,6 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
 		List<PropertyInfo> plist;
 		List<PropertyInfo> plist;
 		N->get()->get_property_list(&plist);
 		N->get()->get_property_list(&plist);
 
 
-		if (!current_node)
-			continue;
-
 		for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
 		for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
 
 
 			if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
 			if (!(E->get().usage & PROPERTY_USAGE_STORAGE))