diff --git a/editor/run/game_view_plugin.cpp b/editor/run/game_view_plugin.cpp index 6ccd4f5931..9c137bdfd2 100644 --- a/editor/run/game_view_plugin.cpp +++ b/editor/run/game_view_plugin.cpp @@ -81,6 +81,7 @@ void GameViewDebugger::_session_started(Ref 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 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 diff --git a/editor/scene/3d/node_3d_editor_plugin.cpp b/editor/scene/3d/node_3d_editor_plugin.cpp index 974c1373df..050315d1da 100644 --- a/editor/scene/3d/node_3d_editor_plugin.cpp +++ b/editor/scene/3d/node_3d_editor_plugin.cpp @@ -2054,10 +2054,10 @@ void Node3DEditorViewport::input(const Ref &p_event) { void Node3DEditorViewport::_sinput(const Ref &p_event) { const Ref 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 &p_event) { } Ref 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 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 k_mod = event_mod; + k_mod->set_keycode(code); } if (_edit.mode == TRANSFORM_NONE) { diff --git a/scene/debugger/runtime_node_select.cpp b/scene/debugger/runtime_node_select.cpp index 1e794ef323..eac038700b 100644 --- a/scene/debugger/runtime_node_select.cpp +++ b/scene/debugger/runtime_node_select.cpp @@ -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 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 = 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 &p_event) { Ref 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 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 k = p_event; if (k.is_valid() && k->get_physical_keycode() == Key::ESCAPE) { view_3d_controller->set_freelook_enabled(false); diff --git a/scene/debugger/runtime_node_select.h b/scene/debugger/runtime_node_select.h index 67cadf6c4e..23af80c588 100644 --- a/scene/debugger/runtime_node_select.h +++ b/scene/debugger/runtime_node_select.h @@ -131,6 +131,9 @@ private: real_t camera_znear = 0; real_t camera_zfar = 0; + Key freelook_modifier = Key::NONE; + Ref freelook_toggle; + struct SelectionBox : public RefCounted { RID instance; RID instance_ofs; diff --git a/scene/debugger/view_3d_controller.cpp b/scene/debugger/view_3d_controller.cpp index f0c2274b36..864bed53f4 100644 --- a/scene/debugger/view_3d_controller.cpp +++ b/scene/debugger/view_3d_controller.cpp @@ -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 = inputs[p_name]; if (shortcut.is_null()) { - return p_true_if_null; + return p_true_if_empty; } const Array shortcuts = shortcut->get_events(); - Ref 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 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 = inputs[p_name]; - if (shortcut.is_null()) { - return true; - } - - const Array shortcuts = shortcut->get_events(); - Ref 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 &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 &p_shortcut) { ERR_FAIL_INDEX(0, SHORTCUT_MAX); ERR_FAIL_COND(p_shortcut.is_null()); diff --git a/scene/debugger/view_3d_controller.h b/scene/debugger/view_3d_controller.h index c61c78c865..7eabb7edaf 100644 --- a/scene/debugger/view_3d_controller.h +++ b/scene/debugger/view_3d_controller.h @@ -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 &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 &p_shortcut); void set_navigation_scheme(const NavigationScheme p_scheme) { navigation_scheme = p_scheme; }