Przeglądaj źródła

Merge pull request #26748 from raphael10241024/instance

Fix editor crash when saving a scene containing an inherited scene instance.
Rémi Verschelde 6 lat temu
rodzic
commit
ddba2e7b47
2 zmienionych plików z 29 dodań i 1 usunięć
  1. 28 1
      editor/scene_tree_dock.cpp
  2. 1 0
      editor/scene_tree_dock.h

+ 28 - 1
editor/scene_tree_dock.cpp

@@ -269,7 +269,7 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base)
 bool SceneTreeDock::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) {
 	int childCount = p_desired_node->get_child_count();
 
-	if (p_desired_node->get_filename() == p_target_scene_path) {
+	if (_track_inherit(p_target_scene_path, p_desired_node)) {
 		return true;
 	}
 
@@ -284,6 +284,33 @@ bool SceneTreeDock::_cyclical_dependency_exists(const String &p_target_scene_pat
 	return false;
 }
 
+bool SceneTreeDock::_track_inherit(const String &p_target_scene_path, Node *p_desired_node) {
+	Node *p = p_desired_node;
+	bool result = false;
+	Vector<Node *> instances;
+	while (true) {
+		if (p->get_filename() == p_target_scene_path) {
+			result = true;
+			break;
+		}
+		Ref<SceneState> ss = p->get_scene_inherited_state();
+		if (ss.is_valid()) {
+			String path = ss->get_path();
+			Ref<PackedScene> data = ResourceLoader::load(path);
+			if (data.is_valid()) {
+				p = data->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
+				instances.push_back(p);
+			} else
+				break;
+		} else
+			break;
+	}
+	for (int i = 0; i < instances.size(); i++) {
+		memdelete(instances[i]);
+	}
+	return result;
+}
+
 void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 
 	current_option = p_tool;

+ 1 - 0
editor/scene_tree_dock.h

@@ -165,6 +165,7 @@ class SceneTreeDock : public VBoxContainer {
 	void _script_open_request(const Ref<Script> &p_script);
 
 	bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node);
+	bool _track_inherit(const String &p_target_scene_path, Node *p_desired_node);
 
 	void _node_selected();
 	void _node_renamed();