Can't stop camera from rotating on Z Axis

I’m making an fps game and attempting to rotate a camera up and down the x/y axes using mouse input. The camera continues to rotate along the z axis making gameplay impossible. I am also having trouble limiting rotation to ~180 for the y axis. It may be a dumb question but I’m fairly new. Here is my code.

using UnityEngine;

public class CameraLook : MonoBehaviour
{
float xSensitivity = 5.0f;
float ySensitivity = 5.0f;

void Update()
{
    float X = Input.GetAxis("Mouse X") * xSensitivity;
    float Y = Input.GetAxis("Mouse Y") * ySensitivity;

    transform.Rotate(0, X, 0);
    transform.Rotate(-Y, 0, 0);

}

Hey @unity_DFr1mq6f7MWYug,

I’d suggest setting transform.eulerAngles once instead of using transform.Rotate multiple times. Also, you will probably want smoothing for your camera motion.

Below is a simple camera controller that rotates smoothly on the X/Y axes. It sets a target rotation based on mouse input, and smooths between that and the current rotation. It prevents flipping over by using the Mathf.Clamp method to limit the rotation around the X axis.

I adapted it from a built-in camera controller Unity has – UnityTemplateProjects.SimpleCameraController – it’s the one that is on the default camera for projects created using the Univeral Render Pipeline template, and I highly suggest studying its source code. I made the below mostly by removing features from it to make it simpler, only adding the flip-over prevention. Hope this helps!


using UnityEngine;

public class CameraController : MonoBehaviour
{
    class CameraRotation
    {
        public float yaw, pitch, roll;

        public void InitializeFromTransform(Transform t)
        {
            pitch = t.eulerAngles.x;
            yaw = t.eulerAngles.y;
            roll = t.eulerAngles.z;
        }

        public void LerpTowards(CameraRotation target, float rotationLerpPct)
        {
            yaw = Mathf.Lerp(yaw, target.yaw, rotationLerpPct);
            pitch = Mathf.Lerp(pitch, target.pitch, rotationLerpPct);
            roll = Mathf.Lerp(roll, target.roll, rotationLerpPct);
        }

        public void UpdateTransform(Transform t)
        {
            t.eulerAngles = new Vector3(pitch, yaw, roll);
        }
    }

    CameraRotation targetRotation = new CameraRotation();
    CameraRotation currentRotation = new CameraRotation();

    [Tooltip("Time it takes to interpolate camera rotation 99% of the way to the target."), Range(0.001f, 1f)]
    public float lerpTime = 0.01f;

    public float xSensitivity = 1f;
    public float ySensitivity = 1f;

    void OnDisable() { Cursor.lockState = CursorLockMode.None; }

    void OnEnable()
    {
        targetRotation.InitializeFromTransform(transform);
        currentRotation.InitializeFromTransform(transform);
        // This makes the cursor hidden -- hit Escape to get your cursor back so you can exit play mode
        Cursor.lockState = CursorLockMode.Locked;
    }

    void Update()
    {
        // Update the target rotation based on mouse input
        var mouseInput = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y") * -1);
        targetRotation.yaw += mouseInput.x * xSensitivity;
        targetRotation.pitch += mouseInput.y * ySensitivity;

        // Don't allow the camera to flip upside down
        targetRotation.pitch = Mathf.Clamp(targetRotation.pitch, -90, 90);

        // Calculate the new rotation using framerate-independent interpolation
        var lerpPct = 1f - Mathf.Exp(Mathf.Log(0.01f) / lerpTime * Time.deltaTime);
        currentRotation.LerpTowards(targetRotation, lerpPct);

        // Commit the rotation changes to the transform
        currentRotation.UpdateTransform(transform);
    }
}