Weird 3D camera X rotation behaviour

Godot Version

v4.4.1.stable.mono.official.49a5bc7b6

Question

` Hi yall! I am trying to make a 3D character controller, it went very well. I heard about bone attachment. So I used it to attach the camera it so the camera is synced with the player’s head.

After doing this, looking up and downusing mouse ‘X ROTATION’ started to glitch. After few rotations and walking a little bit it started to rotating instead of up and down it started rotating up and down with like 45 degress added to it around axis Y. You can see that on video.`

This did not happened when the camera parent 3D node was not attached to the bone.

Script: extends CharacterBody3Dvar speedconst WALK_SPEED = 5.0const SPRINT_SPEED - Pastebin.com
Layout:

Video: https://youtu.be/zSezI3HIlmM

This is called Gimbal Lock. It happens when you try to rotate something on the x and y axis using Euler coordinates. You can solve it by rotating a node in the y-axis, and the camera as a child of that node on the x-axis. Here’s a good tutorial on it.

1 Like

The link dosen’t work. But thanks I will look at it.

Fixed the link.

is there any other solution? I mean rotation system that dosent have gimball

There might be, but I have yet to find it. Is there a reason this solution won’t work for you?

I tried what have you said but it did not work. I heard eular angles are a bad habbit. I have found some forum thread with code here: https://forum.godotengine.org/t/using-quaternion-math-for-camera-controls-because-i-am-scared-of-euler-angles/74123/2

But thanks for help!

1 Like

I did some googling. Seems like it depends on what you’re doing. Using 3D transforms — Godot Engine (stable) documentation in English Here’s the Godot docs on what to do.

I also found this thread which I found the last response interesting.

@pennyloafers I noticed that you commented on the Godot doc I linked above. Do you know any good tutorials on creating a first person controller using quaternion transforms?

Unfortunately Godot is not a quaternion engine. Each time you need to rotate you need to convert from a transform to a quat and back again. And manufacturing/manipulating a quat by hand is not intuitive because of the complex domain it utilizes.

Now putting my mind to it. You could try making a quat representation of the transform that can be rotated by some axis you define as orthogonal to the current forward vector.

To do a basic rotation of quats need to multiply multiple quaternions like: q•p/q to perform the rotation q to p

But its a lot easier to just use transforms matrix, here is the simplest means to do so as an example i wrote.

func look(mouse_motion:Vector2):
# look up/down
# rotate the object using the local coordinates, prevents gimbal lock
	rotate_object_local(Vector3.LEFT, mouse_motion.y * speed)
# limit the y basis vector to upper hemisphere
	if transform.basis.y.y < 0.0:
		self.rotation.x = -PI/2.0 * sign(transform.basis.z.y)
# look left/right
	rotate_y(-mouse_motion.x * speed)

you can also splite the axi into several nodes like: camera pan or camara tilt to utilize multiple independent transform3Ds that can’t be gimbal locked

1 Like

All the quaternion math is already provided by the engine. This just isn’t a quaternion problem though.

dragonforge-dev already provided the answer in the first post. Here’s another link to a simple fps camera (same site): Basic FPS Character :: Godot 4 Recipes

1 Like

I have found the solution for fps using the quaterion transform. I used the code from my latest reply. I modified already existing controller.

There is the code for looking around: func _unhandled_input(event): if event is InputEventMouseMotion: set_quater - Pastebin.com

Feel free to suggest any suggestion to the code.

1 Like

I still think this is unnecessary, considering also that you don’t actually utilize the power of quaternions, instead jumping back and forth from euler space to quaternion space.