Using Quaternion math for Camera Controls Because I am Scared of Euler Angles

Godot Version

4.2.2.stable

Question

I am a new learner for GameDev in general, so I am trying to be thorough in my learning to avoid bad habits. In my reading I have read about the dangers of Gimbal lock (and how using Euler angles for rotation should be avoided in general.) I then went on to read here that Quaternion operations tend to be considered efficient.

My issue is that while the following code I have added to the built-in CharacterBody3D class does what I want it to do (excusing how the camera does not clamp vertically) the motion is jumpy and lags behind my mouse. I have seen other methods that use nested pivot nodes, but I am mostly interested in using pure Quaternion math to achieve this as a personal exercise.

const CAMERA_SENSITIVITY = 0.002

@onready var spring_arm = $SpringArm3D

func _unhandled_input(event):
	if event is InputEventMouseMotion:
		spring_arm.set_quaternion(
			Quaternion(
				Vector3.UP, 
				CAMERA_SENSITIVITY * -event.relative.x) 
			* spring_arm.quaternion)
			
		spring_arm.set_quaternion(
			Quaternion(
				spring_arm.basis.x, 
				CAMERA_SENSITIVITY * -event.relative.y) 
			* spring_arm.quaternion)

Here is my node structure:
CharacterBody3D
| CollisionShape3D
| MeshInstance3D
| SpringArm3D
| | Camera3D

If there are any errors that I have not mentioned, please do not hesitate to let me know!

1 Like

What do you mean by “jumpy” in regards to the camera’s motion? That might help with finding a solution!

In-case this might be the fix: The mouse won’t move the camera if the cursor exits the bounds of the window. When the mouse exits and re-enters the window area, it will cause a jump. If you want the mouse to stay in the window (and thus always move the camera without issue) you can add this to the ready() function of your script:

Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

Note that this will hide the mouse as well. You will need to alt-tab or force close the game window (via Alt-F4) in order to regain control of the mouse.

Thank you for your response. By “jumpy,” I mean there is stuttering in the camera when I move my mouse smoothly across the screen, as if some of the inputs are getting lost. I will try it again with the mouse captured to see if that improves the issue. Thank you!

Tangentially related, but I saw this post on naming conventions for transforms that you may find interesting:

1 Like

Very nice, thank you!

1 Like