Browse Source

Fix loading packed scene with editable children at runtime

At runtime, packed scenes with nodes marked as editable instance where
saved with node type tags, which prevented the scene to be then loaded
as an instance, causing duplicated nodes in the tree.

This change ensures nodes marked as editable instances and their owned
children are properly set as instances.

That doesn't make a difference in the editor, since such nodes where
already set as instances based on their instance state, but it helps
at runtime where instance states are disabled.

Co-authored-by: latorril <[email protected]>
(cherry picked from commit fab88a810ccd32ed5a573050171d12c73f69a668)
PouleyKetchoupp 4 years ago
parent
commit
389e67aa98
1 changed files with 9 additions and 2 deletions
  1. 9 2
      scene/resources/packed_scene.cpp

+ 9 - 2
scene/resources/packed_scene.cpp

@@ -377,10 +377,17 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
 		return OK;
 	}
 
-	// save the child instanced scenes that are chosen as editable, so they can be restored
+	bool is_editable_instance = false;
+
+	// save the child instantiated scenes that are chosen as editable, so they can be restored
 	// upon load back
 	if (p_node != p_owner && p_node->get_filename() != String() && p_owner->is_editable_instance(p_node)) {
 		editable_instances.push_back(p_owner->get_path_to(p_node));
+		// Node is the root of an editable instance.
+		is_editable_instance = true;
+	} else if (p_node->get_owner() && p_node->get_owner() != p_owner && p_owner->is_editable_instance(p_node->get_owner())) {
+		// Node is part of an editable instance.
+		is_editable_instance = true;
 	}
 
 	NodeData nd;
@@ -610,7 +617,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
 
 	// Save the right type. If this node was created by an instance
 	// then flag that the node should not be created but reused
-	if (pack_state_stack.empty()) {
+	if (pack_state_stack.empty() && !is_editable_instance) {
 		//this node is not part of an instancing process, so save the type
 		nd.type = _nm_get_string(p_node->get_class(), name_map);
 	} else {