From 363c95ce13366070c3aa8cc5547d3d7868411855 Mon Sep 17 00:00:00 2001 From: ryevdokimov Date: Sat, 2 May 2026 13:41:51 -0400 Subject: [PATCH] Fix 3D transform gizmo visibility after node lock/unlock --- editor/scene/3d/node_3d_editor_plugin.cpp | 23 +++++++++++++++++++++-- editor/scene/3d/node_3d_editor_plugin.h | 1 + editor/scene/scene_tree_editor.cpp | 15 +++++++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/editor/scene/3d/node_3d_editor_plugin.cpp b/editor/scene/3d/node_3d_editor_plugin.cpp index 974c1373df..483a6ba79e 100644 --- a/editor/scene/3d/node_3d_editor_plugin.cpp +++ b/editor/scene/3d/node_3d_editor_plugin.cpp @@ -599,6 +599,17 @@ int Node3DEditorViewport::get_selected_count() const { return count; } +bool Node3DEditorViewport::_has_unlocked_selection() const { + const List &selection = editor_selection->get_top_selected_node_list(); + for (Node *E : selection) { + Node3D *sp = Object::cast_to(E); + if (sp && !_is_node_locked(sp)) { + return true; + } + } + return false; +} + void Node3DEditorViewport::cancel_transform() { const List &selection = editor_selection->get_top_selected_node_list(); @@ -2732,7 +2743,7 @@ void Node3DEditorViewport::_sinput(const Ref &p_event) { bool is_select_mode = (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_TRANSFORM); bool is_clicked_selected = editor_selection->is_selected(ObjectDB::get_instance(clicked)); - if (_edit.mode == TRANSFORM_NONE && (is_select_mode || is_clicked_selected)) { + if (_edit.mode == TRANSFORM_NONE && (is_select_mode || is_clicked_selected) && _has_unlocked_selection()) { _compute_edit(_edit.original_mouse_pos); clicked = ObjectID(); _edit.mode = TRANSFORM_TRANSLATE; @@ -3002,7 +3013,7 @@ void Node3DEditorViewport::_sinput(const Ref &p_event) { begin_transform(TRANSFORM_SCALE, true); } } - if (ED_IS_SHORTCUT("spatial_editor/collision_reposition", event_mod) && editor_selection->get_top_selected_node_list().size() == 1 && !collision_reposition) { + if (ED_IS_SHORTCUT("spatial_editor/collision_reposition", event_mod) && editor_selection->get_top_selected_node_list().size() == 1 && !collision_reposition && _has_unlocked_selection()) { if (_edit.mode == TRANSFORM_NONE || _edit.instant) { if (_edit.mode == TRANSFORM_NONE) { _compute_edit(_edit.mouse_pos); @@ -6109,6 +6120,10 @@ void Node3DEditorViewport::begin_transform(TransformMode p_mode, bool instant) { } if (get_selected_count() > 0) { + if (!_has_unlocked_selection()) { + return; + } + _edit.children_original_globals.clear(); _edit.mode = p_mode; @@ -8196,6 +8211,8 @@ void Node3DEditor::_menu_item_pressed(int p_option) { undo_redo->add_do_method(this, "_refresh_menu_icons"); undo_redo->add_undo_method(this, "_refresh_menu_icons"); + undo_redo->add_do_method(this, "update_transform_gizmo"); + undo_redo->add_undo_method(this, "update_transform_gizmo"); undo_redo->commit_action(); } break; case MENU_UNLOCK_SELECTED: { @@ -8217,6 +8234,8 @@ void Node3DEditor::_menu_item_pressed(int p_option) { undo_redo->add_do_method(this, "_refresh_menu_icons"); undo_redo->add_undo_method(this, "_refresh_menu_icons"); + undo_redo->add_do_method(this, "update_transform_gizmo"); + undo_redo->add_undo_method(this, "update_transform_gizmo"); undo_redo->commit_action(); } break; case MENU_GROUP_SELECTED: { diff --git a/editor/scene/3d/node_3d_editor_plugin.h b/editor/scene/3d/node_3d_editor_plugin.h index 5e7310922f..607d7304ea 100644 --- a/editor/scene/3d/node_3d_editor_plugin.h +++ b/editor/scene/3d/node_3d_editor_plugin.h @@ -302,6 +302,7 @@ private: Transform3D _get_camera_transform() const; int get_selected_count() const; + bool _has_unlocked_selection() const; void cancel_transform(); void _update_shrink(); diff --git a/editor/scene/scene_tree_editor.cpp b/editor/scene/scene_tree_editor.cpp index 505a78d5e3..1bb1021644 100644 --- a/editor/scene/scene_tree_editor.cpp +++ b/editor/scene/scene_tree_editor.cpp @@ -45,6 +45,7 @@ #include "editor/editor_undo_redo_manager.h" #include "editor/file_system/editor_file_system.h" #include "editor/gui/filter_line_edit.h" +#include "editor/scene/3d/node_3d_editor_plugin.h" #include "editor/scene/canvas_item_editor_plugin.h" #include "editor/script/script_editor_plugin.h" #include "editor/settings/editor_settings.h" @@ -144,8 +145,18 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i undo_redo->add_undo_method(n, "set_meta", "_edit_lock_", true); undo_redo->add_do_method(this, "emit_signal", "node_changed"); undo_redo->add_undo_method(this, "emit_signal", "node_changed"); - undo_redo->add_do_method(CanvasItemEditor::get_singleton(), "emit_signal", "item_lock_status_changed"); - undo_redo->add_undo_method(CanvasItemEditor::get_singleton(), "emit_signal", "item_lock_status_changed"); + if (Object::cast_to(n)) { + undo_redo->add_do_method(CanvasItemEditor::get_singleton(), "emit_signal", "item_lock_status_changed"); + undo_redo->add_undo_method(CanvasItemEditor::get_singleton(), "emit_signal", "item_lock_status_changed"); + } else if (Object::cast_to(n)) { + Node3DEditor *node_3d_editor = Node3DEditor::get_singleton(); + undo_redo->add_do_method(node_3d_editor, "emit_signal", "item_lock_status_changed"); + undo_redo->add_undo_method(node_3d_editor, "emit_signal", "item_lock_status_changed"); + undo_redo->add_do_method(node_3d_editor, "_refresh_menu_icons"); + undo_redo->add_undo_method(node_3d_editor, "_refresh_menu_icons"); + undo_redo->add_do_method(node_3d_editor, "update_transform_gizmo"); + undo_redo->add_undo_method(node_3d_editor, "update_transform_gizmo"); + } undo_redo->commit_action(); } else if (p_id == BUTTON_PIN) { if (n->is_class("AnimationMixer")) {