The following code is controlling a camera:
float yRotation = Input.GetAxis("Mouse Y") * rotationSpeed;
yRotation *= Time.deltaTime;
float xRotation = Input.GetAxis("Mouse X") * rotationSpeed;
xRotation *= Time.deltaTime;
transform.Rotate(yRotation, xRotation, 0, Space.World);
Rotation speed is currently set to 50, but that’s not the problem. My problem is that for some reason unknown to me, this code manages to alter the z rotation of the camera. As far as I can tell, it really shouldn’t!!!(1) Any insights are welcome.
When you rotate around the Y axis, the X axis stay fixed (you’re using Space.World). If you rotate 90 degrees to the right, for instance, the camera will end looking to the X direction. At this angle, if you try to rotate “vertically”, you actually will tilt left and right. Changing to Space.Self just inverts the problem: if you rotate around the X axis (vertically), the local Y axis gets tilted, and the horizontal rotation too.
You can make a mouse look script doing some changes in your code:
float rotationSpeed = 50;
float yRotation = 0;
float xRotation = 0;
yRotation -= Input.GetAxis("Mouse Y") * rotationSpeed * Time.deltaTime;
yRotation = Mathf.Clamp(yRotation, -80, 80);
xRotation += Input.GetAxis("Mouse X") * rotationSpeed * Time.deltaTime;
xRotation = xRotation % 360;
transform.localEulerAngles = new Vector3(yRotation, xRotation, 0);
The trick here is that Unity calculates a rotation equivalent to what we expect: it calculates the vertical (around X) rotation first, then combine it with the horizontal rotation (around Y) - without tilting any angle.
The vertical rotation is limited to +/- 80 degrees to avoid a gimbal lock when the angle reaches +/- 90 degrees, and the inversion of the horizontal axis when the angle surpasses these values.
How can i do this without clamping the y angles. I have been trying (unsuccesfully) to write a main camera controller that emulates a spaceship and i am getting gimbal lock even though i am using quaternions ?