diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 5d5bb1242d3..9b58c18f515 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -559,6 +559,8 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { hints["editors/3d/navigation_feel/manipulation_translation_inertia"] = PropertyInfo(Variant::FLOAT, "editors/3d/navigation_feel/manipulation_translation_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); // 3D: Freelook + _initial_set("editors/3d/freelook/freelook_navigation_scheme", false); + hints["editors/3d/freelook/freelook_navigation_scheme"] = PropertyInfo(Variant::INT, "editors/3d/freelook/freelook_navigation_scheme", PROPERTY_HINT_ENUM, "Default,Partially Axis-Locked (id Tech),Fully Axis-Locked (Minecraft)"); _initial_set("editors/3d/freelook/freelook_inertia", 0.1); hints["editors/3d/freelook/freelook_inertia"] = PropertyInfo(Variant::FLOAT, "editors/3d/freelook/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); _initial_set("editors/3d/freelook/freelook_base_speed", 5.0); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 354c951a7c6..f51b9b20e40 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2287,9 +2287,27 @@ void Node3DEditorViewport::_update_freelook(real_t delta) { return; } - const Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1)); + const FreelookNavigationScheme navigation_scheme = (FreelookNavigationScheme)EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_navigation_scheme").operator int(); + + Vector3 forward; + if (navigation_scheme == FREELOOK_FULLY_AXIS_LOCKED) { + // Forward/backward keys will always go straight forward/backward, never moving on the Y axis. + forward = Vector3(0, 0, -1).rotated(Vector3(0, 1, 0), camera->get_rotation().y); + } else { + // Forward/backward keys will be relative to the camera pitch. + forward = camera->get_transform().basis.xform(Vector3(0, 0, -1)); + } + const Vector3 right = camera->get_transform().basis.xform(Vector3(1, 0, 0)); - const Vector3 up = camera->get_transform().basis.xform(Vector3(0, 1, 0)); + + Vector3 up; + if (navigation_scheme == FREELOOK_PARTIALLY_AXIS_LOCKED || navigation_scheme == FREELOOK_FULLY_AXIS_LOCKED) { + // Up/down keys will always go up/down regardless of camera pitch. + up = Vector3(0, 1, 0); + } else { + // Up/down keys will be relative to the camera pitch. + up = camera->get_transform().basis.xform(Vector3(0, 1, 0)); + } Vector3 direction; diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 2c3b15cfc8d..1a998a45f08 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -241,6 +241,12 @@ public: NAVIGATION_MODO, }; + enum FreelookNavigationScheme { + FREELOOK_DEFAULT, + FREELOOK_PARTIALLY_AXIS_LOCKED, + FREELOOK_FULLY_AXIS_LOCKED, + }; + private: float cpu_time_history[FRAME_TIME_HISTORY]; int cpu_time_history_index;