Skip to content

Conversation

@aaronfranke
Copy link
Member

@aaronfranke aaronfranke commented Aug 14, 2025

This PR aligns the Godot editor's free look camera movement controls and features with that of other 3D software. Unreal Engine already uses R/F for local up/down.

In master, the E and Q keys are configurable. By default they perform local up/down movement, but if you change editors/3d/freelook/freelook_navigation_scheme, they can be global. This default is the same as the behavior of Unity. Also, both Unity and Godot currently do not have any dedicated controls to move the camera globally up/down, only locally, unless changing that editor setting, but then it's only globally until you change it back.

This PR adds a new dedicated binding for always local up/down, R and F keys, and adds a new feature, global up/down movement, to the Space and Ctrl keys. These features are found in most 3D software, though not always the same keys.

In summary, the controls now look like this:

  • R and F: Always local up/down.
  • Space and Ctrl: Always global up/down.
  • E and Q: Configurable up/down based on editors/3d/freelook/freelook_navigation_scheme (kept same as master).

This also matches 6DoF games such as Elite: Dangerous and Pioneer which use R and F for local up/down, and while 6DoF games don't typically need global up/down, they use E and Q for rolling instead. If Godot ever gets a 6DoF editor camera (which would be nice actually, but that's a separate discussion), this allows the R and F keys to act as local up/down movement for both, with E and Q being rolling the camera in the 6DoF mode.

Note that these keys are only active when holding right-click, so this doesn't conflict with F to focus or R to scale, in the same way that the Q/W/E keys already don't conflict with the select/move/rotate toolbar hotkeys.

Old PR description:

Details

This PR changes local up/down to use the R and F keys, and adds a new feature, global up/down movement, to the E and Q keys. These bindings match the behavior in most 3D software, such as Unreal Engine and Blender's fly/walk navigation. This behavior is a superset of what Unity and older Godot versions have, but with different key bindings.

This also matches 6DoF games such as Elite: Dangerous and Pioneer which use R and F for local up/down, and while 6DoF games don't typically need global up/down, they use E and Q for rolling instead. If Godot ever gets a 6DoF editor camera (which would be nice actually, but that's a separate discussion), this allows the R and F keys to act as local up/down movement for both, with E and Q being either global up/down or rolling the camera.

If desired, I have another branch that only adds the R/F key bindings but leaves E/Q unchanged, and I could open a pull request for that on older Godot branches so that R/F works in all recent versions of Godot.

@aaronfranke aaronfranke added this to the 4.6 milestone Aug 14, 2025
@aaronfranke aaronfranke requested a review from Calinou August 14, 2025 02:30
@aaronfranke aaronfranke requested a review from a team as a code owner August 14, 2025 02:30
@Calinou
Copy link
Member

Calinou commented Aug 14, 2025

Remember to check the freelook navigation scheme settings too:

const Node3DEditorViewport::FreelookNavigationScheme navigation_scheme = (Node3DEditorViewport::FreelookNavigationScheme)EDITOR_GET("editors/3d/freelook/freelook_navigation_scheme").operator int();
Vector3 forward;
if (navigation_scheme == Node3DEditorViewport::FreelookNavigationScheme::FREELOOK_FULLY_AXIS_LOCKED) {
// Forward/backward keys will always go straight forward/backward, never moving on the Y axis.
forward = Vector3(0, 0, delta_normalized.y).rotated(Vector3(0, 1, 0), viewport->camera->get_rotation().y);
} else {
// Forward/backward keys will be relative to the camera pitch.
forward = viewport->camera->get_transform().basis.xform(Vector3(0, 0, delta_normalized.y));
}

I would prefer keeping Q/E as-is, but I'm OK with introducing R/F for global up/down instead. Ideally, I would use Space/Shift for global up/down (matching Minecraft creative behavior), but we already use Shift as a speed modifier. Maybe Space/Ctrl, but Ctrl is a key you often press (e.g. to toggle snapping).

@aaronfranke
Copy link
Member Author

aaronfranke commented Aug 14, 2025

@Calinou I'm against adding R/F for global up/down because it defeats the purpose of unifying these controls across most 3D software. We could add Space/Ctrl to do this, though, that's a good idea. I don't think people use snapping while moving the camera, right? EDIT: PR updated.

@aaronfranke aaronfranke force-pushed the editor-camera-freelook-controls branch from 167ed1a to 2f9daa6 Compare August 15, 2025 00:09
@aaronfranke aaronfranke changed the title Use R/F keys for local up/down and E/Q for global up/down Use R/F keys for local up/down and Space/Ctrl for global up/down Aug 15, 2025
@aaronfranke aaronfranke force-pushed the editor-camera-freelook-controls branch from 2f9daa6 to 594dc6b Compare August 15, 2025 00:21
@aaronfranke aaronfranke force-pushed the editor-camera-freelook-controls branch from 594dc6b to cea8ae8 Compare October 22, 2025 08:38
Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, it works as expected. Code looks good to me.

However, when you press Shift + F to toggle freelook (instead of holding down the right mouse button), the camera will go downwards until you release F. This keypress should be ignored as it's what triggered the initial freelook toggle.

@Calinou
Copy link
Member

Calinou commented Oct 22, 2025

@passivestar @lander-vr I'd also appreciate your input on this PR in terms of UX 🙂

@passivestar
Copy link
Contributor

I think this is fine, although you could have just 4 actions instead of 6:

  • freelook_up E
  • freelook_down Q
  • freelook_up_alt_axis Space
  • freelook_down_alt_axis Ctrl

The 2 new actions would also depend on freelook_navigation_scheme but move on the opposite axis between local/global. This approach would embrace the existence of freelook_navigation_scheme instead working around it with new local/global shortcuts. Another alternative would be to deprecate freelook_navigation_scheme and leave only explicit local/global shortcuts, but that would be a more intrusive change, not to mention that it also affects the forward vector and not just up, so that is probably not a good option

If you want to add R/F bindings by default to better match the expectations of users coming from other software you don't need extra actions for those either, you could just add them to the existing freelook_up and freelook_down actions alongside the already bound Q/E

@aaronfranke aaronfranke force-pushed the editor-camera-freelook-controls branch from cea8ae8 to bd427f5 Compare October 23, 2025 00:57
@aaronfranke
Copy link
Member Author

@Calinou I updated the PR to fix Shift+F conflicting with the controls. Now, right-mouse-activated freelook allows users to press Shift and/or F without accidentally disabling freelook, and Shift+F without right mouse still works.

@passivestar The idea is to provide R/F and Space/Ctrl as dedicated keys that always perform these functions, while E/Q are configurable. This way users can configure what they want E/Q to do, without affecting R/F. If R/F were bound to the same actions as E/Q, this ability would not exist.

@passivestar
Copy link
Contributor

This way users can configure what they want E/Q to do, without affecting R/F.

Do you expect the user to need both dedicated and scheme-dependent keys at the same time while using the editor and to use those 6 different keys? The navigation_scheme setting will probably at most be only ever changed once when the user first downloads godot

@aaronfranke aaronfranke force-pushed the editor-camera-freelook-controls branch from bd427f5 to 63b3fd9 Compare November 4, 2025 03:39
@aaronfranke
Copy link
Member Author

aaronfranke commented Nov 22, 2025

@passivestar Yes, because the point is to give users the freedom regardless of whatever navigation scheme they have selected. It is perfectly valid to want to do a different style of up/down movement independent of the editor setting, so that both up/down behaviors are available regardless of how the users configure the WASDQE keys to behave

Also, more importantly, I want to have consistency between applications. Having these exist on separate keys (R/F and Space/Ctrl) allows users to always press those keys to always get that behavior regardless of application and configuration.

@aaronfranke aaronfranke modified the milestones: 4.6, 4.7 Dec 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants