- Home /
Mouse look script with no world up axis behaves weirdly
So i have a mouse look script for a space game, where the world doesn't have an 'up' direction. It is quite hard to explain my problem, i will try to visualize it.
As you can see, the view doesn't get back to normal but also rotates by a bit. What is the problem? The line that does everything:
transform.localRotation *= Quaternion.Euler(-GetMouseY(), GetMouseX(), 0);
The GetMouse()
functions are just Input.GetAxis("Mouse X/Y")
Answer by unity_ek98vnTRplGj8Q · Jan 05, 2021 at 04:25 PM
If I understand correctly, you are asking why applying only X and Y rotations are resulting in a net rotation in the Z axis after a while.
When you rotate a rotated object it rotates it based off of its local rotation. Imagine in your mind that you rotate an object on just on the X axis by 40 degrees so that its now looking down a bit. Then rotate it from this position on its Y axis 10 degrees to its left. Then rotate it back 40 degrees in its X axis the other way. (Rot x by 40, rot y by 10, rot x by -40). This does NOT result in a net rotation of 10 degrees in the Y axis after all is said and done. That is because the rotations are being applied locally, but since the local rotation has changed due to the y rotation, the are not the same net rotation and therefore do not cancel each other out. On top of that, even though you only applied local X and Y rotations, you will notice that you get a small net rotation in the Z axis when all is said and done.
Hopefully that helped you understand whats happening, but if not don't worry because there is a simple fix. Instead of applying small delta rotations every frame to your rotated object, just keep track of a TOTAL rotation and apply it completely every frame. Something like this:
private Vector3 localRot;
void Update(){
localRot += new Vector3(MouseY, MouseX, 0);
transform.localRotation = Quaternion.Euler(localRot);
}
Now instead of applying rotations on top of rotations, you just have 1 rotation that you are applying which ensures that no net Z rotation is introduced.
Wow! That worked absolutely brilliantly! I modified a code a bit for my needs.
if(localRot.x>270f || localRot.x < 90f)
{
localRot += new Vector3(-Get$$anonymous$$ouseY(), Get$$anonymous$$ouseX(), 0);
}
else
{
localRot += new Vector3(-Get$$anonymous$$ouseY(), -Get$$anonymous$$ouseX(), 0);
}
if(localRot.x>360f)
{
localRot = new Vector3(localRot.x - 360f, localRot.y, localRot.z);
}
if (localRot.x < 0f)
{
localRot = new Vector3(localRot.x + 360f, localRot.y, localRot.z);
}
if (localRot.y > 360f)
{
localRot = new Vector3(localRot.x, localRot.y - 360f, localRot.z);
}
if (localRot.y < 0f)
{
localRot = new Vector3(localRot.x, localRot.y + 360f, localRot.z);
}
transform.localRotation = Quaternion.Euler(localRot);
Gimbal lock is a bit of a problem right now, so I might use a better solution in the future.
Cheers!
Your answer
![](https://koobas.hobune.stream/wayback/20220613022723im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Slerping screenshake 0 Answers
Slowly rotating an object while pointing at mouse 0 Answers
Using quaternion for mouse movement? 3 Answers
MouseLook script 90 degrees off 2 Answers