diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml
index a5097521dc45..5e4348ab0287 100644
--- a/doc/classes/EditorSettings.xml
+++ b/doc/classes/EditorSettings.xml
@@ -343,6 +343,10 @@
Size of the default gizmo for moving, rotating, and scaling 3D nodes.
+
+ If [code]true[/code], enables selection of nodes with any gizmo mode, even if a node is already selected.
+ To enable manipulations of nodes outside the gizmo handles [kbd]Alt[/kbd] can be used.
+
If [code]true[/code], enables 3-button mouse emulation mode. This is useful on laptops when using a trackpad.
When 3-button mouse emulation mode is enabled, the pan, zoom and orbit modifiers can always be used in the 3D editor viewport, even when not holding down any mouse button.
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 12a7c3a2ff80..9a166bb2a0c4 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -841,6 +841,9 @@ void EditorSettings::_load_defaults(Ref p_extra_config) {
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "editors/3d/manipulator_gizmo_size", 80, "16,160,1");
EDITOR_SETTING_USAGE(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/manipulator_gizmo_opacity", 0.9, "0,1,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
+ // 3D: Selection
+ _initial_set("editors/3d/alt_gizmo_transform", false);
+
// 2D
_initial_set("editors/2d/grid_color", Color(1.0, 1.0, 1.0, 0.07), true);
_initial_set("editors/2d/guides_color", Color(0.6, 0.0, 0.8), true);
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 0df0274495f3..7394f32242d3 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -1920,6 +1920,24 @@ void Node3DEditorViewport::_sinput(const Ref &p_event) {
bool node_selected = get_selected_count() > 0;
+ if (after != EditorPlugin::AFTER_GUI_INPUT_CUSTOM && (!b->is_alt_pressed() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || !node_selected || EDITOR_GET("editors/3d/alt_gizmo_transform")))) {
+ // Single item selection.
+ clicked = _select_ray(b->get_position());
+
+ if (clicked.is_valid() && !editor_selection->is_selected(Object::cast_to(ObjectDB::get_instance(clicked)))) {
+ selection_in_progress = true;
+ break;
+ }
+
+ if (clicked.is_null()) {
+ // Default to region select.
+ cursor.region_select = true;
+ cursor.region_begin = b->get_position();
+ cursor.region_end = b->get_position();
+ break;
+ }
+ }
+
if (node_selected && ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->is_command_or_control_pressed()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE)) {
begin_transform(TRANSFORM_ROTATE, false);
break;
@@ -1935,20 +1953,6 @@ void Node3DEditorViewport::_sinput(const Ref &p_event) {
break;
}
- if (after != EditorPlugin::AFTER_GUI_INPUT_CUSTOM) {
- // Single item selection.
- clicked = _select_ray(b->get_position());
-
- selection_in_progress = true;
-
- if (clicked.is_null()) {
- // Default to region select.
- cursor.region_select = true;
- cursor.region_begin = b->get_position();
- cursor.region_end = b->get_position();
- }
- }
-
surface->queue_redraw();
} else {
if (_edit.gizmo.is_valid()) {
@@ -1995,7 +1999,6 @@ void Node3DEditorViewport::_sinput(const Ref &p_event) {
set_message("");
spatial_editor->update_transform_gizmo();
}
- surface->queue_redraw();
}
} break;
@@ -2081,12 +2084,10 @@ void Node3DEditorViewport::_sinput(const Ref &p_event) {
} else {
const bool movement_threshold_passed = _edit.original_mouse_pos.distance_to(_edit.mouse_pos) > 8 * EDSCALE;
- if (selection_in_progress && movement_threshold_passed && clicked.is_valid()) {
- if (clicked_wants_append || !editor_selection->is_selected(Object::cast_to(ObjectDB::get_instance(clicked)))) {
- cursor.region_select = true;
- cursor.region_begin = _edit.original_mouse_pos;
- clicked = ObjectID();
- }
+ if ((selection_in_progress || clicked_wants_append) && movement_threshold_passed && clicked.is_valid()) {
+ cursor.region_select = true;
+ cursor.region_begin = _edit.original_mouse_pos;
+ clicked = ObjectID();
}
if (cursor.region_select) {
@@ -2095,7 +2096,7 @@ void Node3DEditorViewport::_sinput(const Ref &p_event) {
return;
}
- if (clicked.is_valid() && movement_threshold_passed) {
+ if (clicked.is_valid() && movement_threshold_passed && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE)) {
_compute_edit(_edit.original_mouse_pos);
clicked = ObjectID();
_edit.mode = TRANSFORM_TRANSLATE;
@@ -2105,7 +2106,9 @@ void Node3DEditorViewport::_sinput(const Ref &p_event) {
return;
}
- update_transform(_get_key_modifier(m) == Key::SHIFT);
+ if (!selection_in_progress) {
+ update_transform(_get_key_modifier(m) == Key::SHIFT);
+ }
}
} else if (m->get_button_mask().has_flag(MouseButtonMask::RIGHT) || freelook_active) {
NavigationMode change_nav_from_shortcut = _get_nav_mode_from_shortcut_check(NAVIGATION_RIGHT_MOUSE, shortcut_check_sets, false);