Limit Camera Rotation

I’ve got a camera childed to a pivot object attached to the player that rotates when the player holds the middle mouse button and drags. It’s working fine, except dragging the mouse side to side makes the camera go up and down, and dragging the mouse up and down makes the camera go side to side, with inverted directions of what I’d like. Here’s my code; can someone show me how to align the camera with the mouse direction properly?

if (Input.GetKeyDown(KeyCode.Mouse2))
        {
            mouseOrigin = Input.mousePosition;
        }

        if (Input.GetKey(KeyCode.Mouse2))
        {
            Vector3 mousePos = Input.mousePosition;
            Quaternion mouseRot = Quaternion.Euler(mouseOrigin - mousePos);
            cameraPivot.transform.rotation = mouseRot;
        }

        if (Input.GetKeyUp(KeyCode.Mouse2))
        {
            cameraPivot.transform.rotation = Quaternion.Euler(0, 0, 0);
        }

You’re at the start of a winding road. Camera interfaces are a study all by themselves, and when you solve this problem you’re going to discover others which mystify.


You’re going to want to find tutorials and example camera ‘systems’, and experiment. Camera interfaces can be quite ‘personal’ and distinctive. You’ll find questions here (and everywhere on game development generally) on how to implement a camera like a user sees in some example game. There’s a lot of ways to control the camera, and lots of little pitfalls.


The Quaternion itself was resurrected from mathematical historical obscurity to solve one of the main issues called gimbal lock (google provides).


Your problem comes from a slight misunderstanding of the difference between the Quaternion and Euler angle representation. The Euler function takes 3 parameters (which can be wrapped into a Vector3) representing rotations in x, y and z axis respectively. All you need is to think carefully about that sentence.


The x axis is left to right, but a rotation in the x axis represents a change in the y and z parameters (x stays constant in this rotation). The y axis rotation is ‘up/down’, but that represents a change in the x and z parameters, where y doesn’t change. When you think about that, you’ll realize that a mouse x coordinate applied to an x axis produces a pitch, not a yaw. The order of the Euler angles are not yaw,pitch and roll, they are the x, y and z axis. It is more like pitch, yaw, roll. Use the 3 parameter version of Euler and supply the inverted y, x (not x, y) parameters from the vector3 you’re calculating, and that will ‘fix’ the problem.


It will expose the next one. There’s a ‘flip’ associated with gimbal lock. You’ll find you can’t easily pitch down beyond facing straight down - you’ll need to limit that, or consider more carefully how to make relative rotations, which becomes that study I mentioned, a longer, winding road of study on how to make cameras do all that you imagine. Here, at least, you’ll move one step forward.

Ok… I didn’t understand most any of that (though thank you for the information.) Not quite there yet. I’ve figured out a new approach, so here’s a different question: I have working rotation now, so how can I limit the rotation of the camera on the x and y axis?

if (Input.GetKey(KeyCode.Mouse2))
        {
            float horizontal = Input.GetAxis("Mouse X") * -1;
            float vertical = Input.GetAxis("Mouse Y") * -1;
            cameraPivot.transform.Rotate(vertical * cameraRotateSpeed, horizontal * cameraRotateSpeed, 0);
        }