Merge pull request #118659 from YeldhamDev/3d_view_shortcut_fixes

Fix some issues with 3D view manipulation
This commit is contained in:
Thaddeus Crews
2026-05-07 11:13:26 -05:00
6 changed files with 104 additions and 42 deletions
+2
View File
@@ -81,6 +81,7 @@ void GameViewDebugger::_session_started(Ref<EditorDebuggerSession> p_session) {
settings["editors/3d/navigation/invert_y_axis"] = EDITOR_GET("editors/3d/navigation/invert_y_axis");
settings["editors/3d/navigation/warped_mouse_panning"] = EDITOR_GET("editors/3d/navigation/warped_mouse_panning");
settings["editors/3d/navigation/pan_mouse_button"] = EDITOR_GET("editors/3d/navigation/pan_mouse_button");
settings["editors/3d/freelook/freelook_activation_modifier"] = EDITOR_GET("editors/3d/freelook/freelook_activation_modifier");
settings["editors/3d/freelook/freelook_navigation_scheme"] = EDITOR_GET("editors/3d/freelook/freelook_navigation_scheme");
settings["editors/3d/freelook/freelook_base_speed"] = EDITOR_GET("editors/3d/freelook/freelook_base_speed");
settings["editors/3d/freelook/freelook_sensitivity"] = EDITOR_GET("editors/3d/freelook/freelook_sensitivity");
@@ -116,6 +117,7 @@ void GameViewDebugger::_session_started(Ref<EditorDebuggerSession> p_session) {
settings["spatial_editor/freelook_right"] = DebuggerMarshalls::serialize_key_shortcut(ED_GET_SHORTCUT("spatial_editor/freelook_right"));
settings["spatial_editor/freelook_up"] = DebuggerMarshalls::serialize_key_shortcut(ED_GET_SHORTCUT("spatial_editor/freelook_up"));
settings["spatial_editor/freelook_down"] = DebuggerMarshalls::serialize_key_shortcut(ED_GET_SHORTCUT("spatial_editor/freelook_down"));
settings["spatial_editor/freelook_toggle"] = DebuggerMarshalls::serialize_key_shortcut(ED_GET_SHORTCUT("spatial_editor/freelook_toggle"));
settings["spatial_editor/freelook_speed_modifier"] = DebuggerMarshalls::serialize_key_shortcut(ED_GET_SHORTCUT("spatial_editor/freelook_speed_modifier"));
settings["spatial_editor/freelook_slow_modifier"] = DebuggerMarshalls::serialize_key_shortcut(ED_GET_SHORTCUT("spatial_editor/freelook_slow_modifier"));
#endif // _3D_DISABLED
+9 -11
View File
@@ -2054,10 +2054,10 @@ void Node3DEditorViewport::input(const Ref<InputEvent> &p_event) {
void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
const Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed() && EDITOR_GET("editors/3d/navigation/emulate_numpad")) {
const Key code = k->get_physical_keycode();
if (code >= Key::KEY_0 && code <= Key::KEY_9) {
k->set_keycode(code - Key::KEY_0 + Key::KP_0);
if (k.is_valid() && k->is_pressed()) {
const Key code = view_3d_controller->emulate_numpad_key(k->get_physical_keycode());
if (code != k->get_physical_keycode()) {
k->set_keycode(code);
}
}
@@ -2801,13 +2801,11 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
Ref<InputEvent> event_mod = p_event;
if (EDITOR_GET("editors/3d/navigation/emulate_numpad")) {
const Key code = k->get_physical_keycode();
if (code >= Key::KEY_0 && code <= Key::KEY_9) {
event_mod = p_event->duplicate();
Ref<InputEventKey> k_mod = event_mod;
k_mod->set_keycode(code - Key::KEY_0 + Key::KP_0);
}
const Key code = view_3d_controller->emulate_numpad_key(k->get_physical_keycode());
if (code != k->get_physical_keycode()) {
event_mod = p_event->duplicate();
Ref<InputEventKey> k_mod = event_mod;
k_mod->set_keycode(code);
}
if (_edit.mode == TRANSFORM_NONE) {
+63 -2
View File
@@ -128,6 +128,22 @@ void RuntimeNodeSelect::_setup(const Dictionary &p_settings) {
camera_znear = p_settings.get("editors/3d/default_z_near", 0.05);
camera_zfar = p_settings.get("editors/3d/default_z_far", 4'000);
int freelook_mod_idx = p_settings.get("editors/3d/freelook/freelook_activation_modifier", 0);
switch (freelook_mod_idx) {
case 1: {
freelook_modifier = Key::SHIFT;
} break;
case 2: {
freelook_modifier = Key::ALT;
} break;
case 3: {
freelook_modifier = Key::META;
} break;
case 4: {
freelook_modifier = Key::CTRL;
} break;
}
// View3DController Setup
view_3d_controller.instantiate();
@@ -168,6 +184,17 @@ void RuntimeNodeSelect::_setup(const Dictionary &p_settings) {
view_3d_controller->connect("fov_scaled", callable_mp(this, &RuntimeNodeSelect::_fov_scaled));
view_3d_controller->connect("cursor_interpolated", callable_mp(this, &RuntimeNodeSelect::_cursor_interpolated));
freelook_toggle = DebuggerMarshalls::deserialize_key_shortcut(p_settings.get("spatial_editor/freelook_toggle", Array()).operator Array());
if (freelook_toggle.is_valid()) {
for (Ref<InputEventKey> k : freelook_toggle->get_events()) {
if (k->get_physical_keycode() == Key::NONE) {
k->set_keycode(view_3d_controller->emulate_numpad_key(k->get_keycode()));
} else {
k->set_physical_keycode(view_3d_controller->emulate_numpad_key(k->get_physical_keycode()));
}
}
}
#define SET_SHORTCUT(p_name, p_setting) \
{ \
Ref<Shortcut> shortcut = DebuggerMarshalls::deserialize_key_shortcut(p_settings.get(p_setting, Array()).operator Array()); \
@@ -376,7 +403,7 @@ void RuntimeNodeSelect::_update_input_state() {
void RuntimeNodeSelect::_process_frame() {
#ifndef _3D_DISABLED
// Calculate the process time manually, as the time scale can be frozen.
const double process_time = (1.0 / Engine::get_singleton()->get_frames_per_second()) * Engine::get_singleton()->get_unfrozen_time_scale();
const double process_time = (1.0 / Engine::get_singleton()->get_frames_per_second());
if (view_3d_controller->is_freelook_enabled()) {
Input *input = Input::get_singleton();
@@ -1447,10 +1474,44 @@ bool RuntimeNodeSelect::_handle_3d_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> b = p_event;
if (b.is_valid() && b->get_button_index() == MouseButton::RIGHT) {
view_3d_controller->set_freelook_enabled(b->is_pressed());
bool enable_freelook = b->is_pressed();
if (enable_freelook && freelook_modifier != Key::NONE) {
switch (freelook_modifier) {
case Key::SHIFT: {
enable_freelook = b->is_shift_pressed();
} break;
case Key::ALT: {
enable_freelook = b->is_alt_pressed();
} break;
case Key::META: {
enable_freelook = b->is_meta_pressed();
} break;
case Key::CTRL: {
enable_freelook = b->is_ctrl_pressed();
} break;
default:
break;
}
if (!enable_freelook) {
return false;
}
}
view_3d_controller->set_freelook_enabled(enable_freelook);
return true;
}
if (freelook_toggle.is_valid()) {
const Array shortcuts = freelook_toggle->get_events();
for (Ref<InputEventKey> k : shortcuts) {
if (k.is_valid() && p_event->is_match(k) && p_event->is_pressed()) {
view_3d_controller->set_freelook_enabled(!view_3d_controller->is_freelook_enabled());
return true;
}
}
}
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->get_physical_keycode() == Key::ESCAPE) {
view_3d_controller->set_freelook_enabled(false);
+3
View File
@@ -131,6 +131,9 @@ private:
real_t camera_znear = 0;
real_t camera_zfar = 0;
Key freelook_modifier = Key::NONE;
Ref<Shortcut> freelook_toggle;
struct SelectionBox : public RefCounted {
RID instance;
RID instance_ofs;
+23 -28
View File
@@ -55,47 +55,35 @@ Transform3D View3DController::_to_camera_transform(const Cursor &p_cursor) const
return camera_transform;
}
bool View3DController::_is_shortcut_pressed(const ShortcutName p_name, const bool p_true_if_null) {
bool View3DController::_is_shortcut_pressed(const ShortcutName p_name, const bool p_true_if_empty) {
Ref<Shortcut> shortcut = inputs[p_name];
if (shortcut.is_null()) {
return p_true_if_null;
return p_true_if_empty;
}
const Array shortcuts = shortcut->get_events();
Ref<InputEventKey> k;
if (shortcuts.size() > 0) {
k = shortcuts.front();
if (shortcuts.is_empty()) {
return p_true_if_empty;
}
if (k.is_null()) {
return p_true_if_null;
for (Ref<InputEventKey> k : shortcuts) {
if (k.is_null()) {
continue;
}
if (k->get_physical_keycode() == Key::NONE && Input::get_singleton()->is_key_pressed(emulate_numpad_key(k->get_keycode()))) {
return true;
} else if (Input::get_singleton()->is_physical_key_pressed(emulate_numpad_key(k->get_physical_keycode()))) {
return true;
}
}
#define EMULATE_NUMPAD_KEY(p_code) \
(emulate_numpad && p_code >= Key::KEY_0 && p_code <= Key::KEY_9 ? p_code - Key::KEY_0 + Key::KP_0 : p_code)
if (k->get_physical_keycode() == Key::NONE) {
return Input::get_singleton()->is_key_pressed(EMULATE_NUMPAD_KEY(k->get_keycode()));
}
return Input::get_singleton()->is_physical_key_pressed(EMULATE_NUMPAD_KEY(k->get_physical_keycode()));
#undef EMULATE_NUMPAD_KEY
return false;
}
bool View3DController::_is_shortcut_empty(const ShortcutName p_name) {
Ref<Shortcut> shortcut = inputs[p_name];
if (shortcut.is_null()) {
return true;
}
const Array shortcuts = shortcut->get_events();
Ref<InputEventKey> k;
if (shortcuts.size() > 0) {
k = shortcuts.front();
}
return k.is_null();
return shortcut.is_null() || shortcut->get_events().is_empty();
}
View3DController::NavigationMode View3DController::_get_nav_mode_from_shortcuts(NavigationMouseButton p_mouse_button, const Vector<ShortcutCheck> &p_shortcut_checks, bool p_not_empty) {
@@ -622,6 +610,13 @@ void View3DController::scale_cursor_distance(const float p_scale) {
emit_signal(SNAME("cursor_distance_scaled"));
}
Key View3DController::emulate_numpad_key(const Key p_code) const {
if (emulate_numpad && p_code >= Key::KEY_0 && p_code <= Key::KEY_9) {
return p_code - Key::KEY_0 + Key::KP_0;
}
return p_code;
}
void View3DController::set_shortcut(const ShortcutName p_name, const Ref<Shortcut> &p_shortcut) {
ERR_FAIL_INDEX(0, SHORTCUT_MAX);
ERR_FAIL_COND(p_shortcut.is_null());
+4 -1
View File
@@ -33,6 +33,7 @@
#ifndef _3D_DISABLED
#include "core/object/ref_counted.h"
#include "core/os/keyboard.h"
namespace View3DControllerConsts {
constexpr float DISTANCE_DEFAULT = 4;
@@ -247,7 +248,7 @@ private:
}
};
bool _is_shortcut_pressed(const ShortcutName p_name, const bool p_true_if_null = false);
bool _is_shortcut_pressed(const ShortcutName p_name, const bool p_true_if_empty = false);
bool _is_shortcut_empty(const ShortcutName p_name);
NavigationMode _get_nav_mode_from_shortcuts(NavigationMouseButton p_mouse_button, const Vector<ShortcutCheck> &p_shortcut_checks, bool p_not_empty);
@@ -270,6 +271,8 @@ public:
inline Transform3D to_camera_transform() const { return _to_camera_transform(cursor); }
inline Transform3D interp_to_camera_transform() const { return _to_camera_transform(cursor_interp); }
Key emulate_numpad_key(const Key p_code) const;
void set_shortcut(const ShortcutName p_name, const Ref<Shortcut> &p_shortcut);
void set_navigation_scheme(const NavigationScheme p_scheme) { navigation_scheme = p_scheme; }