From 766b45bdd9e81584e989f949110a7461d9ecfab7 Mon Sep 17 00:00:00 2001 From: xuhuisheng Date: Mon, 29 Sep 2025 14:57:29 +0800 Subject: [PATCH] Fix Clear Inheritance error --- editor/docks/scene_tree_dock.cpp | 3 +- editor/editor_data.cpp | 68 ++++++++++++++++++------------ editor/editor_data.h | 1 + editor/scene/scene_tree_editor.cpp | 8 +++- editor/scene/scene_tree_editor.h | 1 + 5 files changed, 51 insertions(+), 30 deletions(-) diff --git a/editor/docks/scene_tree_dock.cpp b/editor/docks/scene_tree_dock.cpp index 66fc27704e2..363d3cb69c5 100644 --- a/editor/docks/scene_tree_dock.cpp +++ b/editor/docks/scene_tree_dock.cpp @@ -1396,7 +1396,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { Node *node = e->get(); if (node) { node->set_scene_inherited_state(Ref()); - scene_tree->update_tree(); + editor_data->reload_scene_from_memory(editor_data->get_edited_scene(), true); + scene_tree->clear_cache(); InspectorDock::get_inspector_singleton()->update_tree(); } } diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index b684be0ee98..693c047ea0e 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -706,33 +706,7 @@ bool EditorData::check_and_update_scene(int p_idx) { bool must_reload = _find_updated_instances(edited_scene[p_idx].root, edited_scene[p_idx].root, checked_scenes); if (must_reload) { - Ref pscene; - pscene.instantiate(); - - EditorProgress ep("update_scene", TTR("Updating Scene"), 2); - ep.step(TTR("Storing local changes..."), 0); - // Pack first, so it stores diffs to previous version of saved scene. - Error err = pscene->pack(edited_scene[p_idx].root); - ERR_FAIL_COND_V(err != OK, false); - ep.step(TTR("Updating scene..."), 1); - Node *new_scene = pscene->instantiate(PackedScene::GEN_EDIT_STATE_MAIN); - ERR_FAIL_NULL_V(new_scene, false); - - // Transfer selection. - List new_selection; - for (const Node *E : edited_scene.write[p_idx].selection) { - NodePath p = edited_scene[p_idx].root->get_path_to(E); - Node *new_node = new_scene->get_node(p); - if (new_node) { - new_selection.push_back(new_node); - } - } - - new_scene->set_scene_file_path(edited_scene[p_idx].root->get_scene_file_path()); - Node *old_root = edited_scene[p_idx].root; - EditorNode::get_singleton()->set_edited_scene(new_scene); - memdelete(old_root); - edited_scene.write[p_idx].selection = new_selection; + reload_scene_from_memory(p_idx, false); return true; } @@ -740,6 +714,46 @@ bool EditorData::check_and_update_scene(int p_idx) { return false; } +bool EditorData::reload_scene_from_memory(int p_idx, bool p_mark_unsaved) { + ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), false); + if (!edited_scene[p_idx].root) { + return false; + } + + Ref pscene; + pscene.instantiate(); + + EditorProgress ep("update_scene", TTR("Updating Scene"), 2); + ep.step(TTR("Storing local changes..."), 0); + // Pack first, so it stores diffs to previous version of saved scene. + Error err = pscene->pack(edited_scene[p_idx].root); + ERR_FAIL_COND_V(err != OK, false); + ep.step(TTR("Updating scene..."), 1); + Node *new_scene = pscene->instantiate(PackedScene::GEN_EDIT_STATE_MAIN); + ERR_FAIL_NULL_V(new_scene, false); + + // Transfer selection. + List new_selection; + for (const Node *E : edited_scene.write[p_idx].selection) { + NodePath p = edited_scene[p_idx].root->get_path_to(E); + Node *new_node = new_scene->get_node(p); + if (new_node) { + new_selection.push_back(new_node); + } + } + + new_scene->set_scene_file_path(edited_scene[p_idx].root->get_scene_file_path()); + Node *old_root = edited_scene[p_idx].root; + EditorNode::get_singleton()->set_edited_scene(new_scene); + memdelete(old_root); + edited_scene.write[p_idx].selection = new_selection; + + if (p_mark_unsaved) { + EditorUndoRedoManager::get_singleton()->clear_history(get_scene_history_id(p_idx)); + } + return true; +} + int EditorData::get_edited_scene() const { return current_edited_scene; } diff --git a/editor/editor_data.h b/editor/editor_data.h index e50ecda22d6..f578d55550e 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -219,6 +219,7 @@ public: void set_edited_scene_live_edit_root(const NodePath &p_root); NodePath get_edited_scene_live_edit_root(); bool check_and_update_scene(int p_idx); + bool reload_scene_from_memory(int p_idx, bool p_mark_unsaved); void move_edited_scene_to_index(int p_idx); bool call_build(); diff --git a/editor/scene/scene_tree_editor.cpp b/editor/scene/scene_tree_editor.cpp index 8dd0fb4b7b1..a485409627b 100644 --- a/editor/scene/scene_tree_editor.cpp +++ b/editor/scene/scene_tree_editor.cpp @@ -1728,13 +1728,17 @@ void SceneTreeEditor::set_display_foreign_nodes(bool p_display) { _update_tree(); } -void SceneTreeEditor::set_valid_types(const Vector &p_valid) { - valid_types = p_valid; +void SceneTreeEditor::clear_cache() { node_cache.force_update = true; callable_mp(this, &SceneTreeEditor::_update_tree).call_deferred(false); tree_dirty = true; } +void SceneTreeEditor::set_valid_types(const Vector &p_valid) { + valid_types = p_valid; + clear_cache(); +} + void SceneTreeEditor::set_editor_selection(EditorSelection *p_selection) { editor_selection = p_selection; tree->set_select_mode(Tree::SELECT_MULTI); diff --git a/editor/scene/scene_tree_editor.h b/editor/scene/scene_tree_editor.h index 2b30707d293..18ae7c5e84a 100644 --- a/editor/scene/scene_tree_editor.h +++ b/editor/scene/scene_tree_editor.h @@ -248,6 +248,7 @@ public: void set_show_enabled_subscene(bool p_show) { show_enabled_subscene = p_show; } void set_valid_types(const Vector &p_valid); + void clear_cache(); inline void update_tree() { _update_tree(); }