Unity FPS Camera Rotation

Hi everyone, I am making a cameraRotation script in Unity and for the vertical Rotation of the camera I tried the following approaches:

  1. Getting the local rotation of the camera, then subtracting the vertical mouse input from it then applying it to the camera local rotation.

  2. Inverting the vertical mouse input and then applying it to the local rotation of the camera

I wanna know which approach is optimal / efficient and if there is any other approach to it

Another question I have is that: Whenever I directly clamp the vertical rotation of the camera and then apply it to the local rotation of the camera it causes crazy jitter when maximum value is reached and when I restore the value in the same variable after clamping everything works fine

newVerticalCameraRot = Mathf.Clamp(newVerticalCameraRot, -90f, 90f);
this.transform.localRotation = Quaternion.Euler(newVerticalCameraRot, 0f, 0f);`

The above works fine

But this doesn’t

Mathf.Clamp(newVerticalCameraRot, -90f, 90f);
this.transform.localRotation = Quaternion.Euler(newVerticalCameraRot, 0f, 0f)

Thank you for reading

Hi there,
When clamping there is an issue in using euler angles. Whenever you pass over 0 or 360 degrees in your calculation, Unity doesn’t like this and that creates the jittering as the camera bounces around.

The solution is to do your calculation and rotation entirely in quaternions which is a little daunting.
I found some code that Unity suggested that uses Quaternions to set the angles but then let’s you clamp it using Euler angles. I altered it a little and this was the result:

            //Horizontal Rotation
            float horizontalRotationDelta = _currentLookDelta.x * _rotateSpeedX * Time.deltaTime;
            transform.rotation *= Quaternion.AngleAxis(horizontalRotationDelta, Vector3.up);

            //Vertical Rotation
            float verticalRotationDelta = -_currentLookDelta.y * _rotateSpeedY * Time.deltaTime;
            transform.rotation *= Quaternion.AngleAxis(verticalRotationDelta, Vector3.right);

            //Clamp vertical rotation
            var eulerAngles = transform.localEulerAngles;
            eulerAngles.z = 0;

            var verticalAngle = transform.localEulerAngles.x;

            if (verticalAngle > 180 && verticalAngle < 360 - _verticalRotationHigherBound)
            {
                eulerAngles.x = 360 - _verticalRotationHigherBound;
            }
            else if(verticalAngle < 180 && verticalAngle > -_verticalRotationLowerBound)
            {
                eulerAngles.x = -_verticalRotationLowerBound;
            }

            transform.localEulerAngles = eulerAngles;

Essentially we are handling the edge cases where you cross 0 and 360 degrees.

1 Like

Thanks @Yitzchak_Cohen for the solution. I was just messing around the code and found that if you clamp the the vertical rotation and store the clamped value in the same variable at the same time then the jittering disappears. IDK why but it worked just fine lol.
Following is some reference:

verticalMouseInput = Mathf.Clamp(verticalMouseInput, maxRange, minRange);

Now use the value and it will work.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms