I am trying to clamp a camera, however the camera "jumps"

I have no ideas at this point as to what can be the issue. I’ve tried to get help multiple times but it never really works. What is at fault here?

  rotateX += Input.GetAxis("Mouse X") * s.YSens * Time.deltaTime;
  rotateY += -Input.GetAxis("Mouse Y") * s.XSens * Time.deltaTime;
  rotateY = Mathf.Clamp(rotateY, -90 - Camera.transform.localRotation.eulerAngles.y, 90 - Camera.transform.localRotation.eulerAngles.y);
  
  Quaternion qq = new Quaternion();
  qq = Quaternion.AngleAxis(rotateY, Vector3.right);
  Camera.transform.localRotation = Camera.transform.localRotation * qq;

Hi, I figured out what the issue was - when converting rotateY into a Quaternion rotation, if rotateY is between 0 and 90, no issue. If it falls just below zero say at -0.1 degrees, the new rotation is at 359.9 degrees. So that’s the cause of the jumpy behavior, since 359.9 would get clamped to 90, which is a jarring change and incorrect.


Using clamp is a bit un-ideal because with it you don’t know whether the clamping was required or not. So if it was required, you won’t know to not rotate your camera this frame. I would suggest using some if statements which are very efficient anyway. The below code worked in Unity properly. Keep in mind though since you track rotateY as cumulative, the mouse rotations are accelerated/decelerated. If you want a fixed rotation rate, just check if rotateY is positive or negative, and apply a fixed amount of rotation to rotX - i.e. add or subtract s.XSens to/from rotX.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CamClamp : MonoBehaviour
{
    float rotateX;
    float rotateY;
    float rotX;

    public Camera Camera;

    void Update()
    {
        rotateX += Input.GetAxis("Mouse X") * 5 * Time.deltaTime;
        rotateY += -Input.GetAxis("Mouse Y") * 5 * Time.deltaTime;

        rotX = Camera.transform.localRotation.eulerAngles.x;

        // We do this so that now the angle rotX is guaranteed to be somewhere between -90 to 90
        if (rotX >= 270)
        {
            rotX -= 360;
        }

        if (rotX > 90)
        {
            rotX = 90;
        }
        else if (rotX < -90)
        {
            rotX = -90;
        }
        else
        {
            rotX += rotateY;
        }

        Camera.transform.localRotation = Quaternion.AngleAxis(rotX, Vector3.right);

    }
}

Last note on convention - when you do rotations, you rotate around axes. I understand your rotateY variable moves the screen up and down along the Y axis, but it is equivalently a rotation around the X axis.