Camera Stutters

So i’ve been trying to create a basic project for a 3d First Person Action Game. I’ve implemented my own little Character Controller and a script that handels camerafollow and rotations. But now when i move in the game and look around at the same time, the camera stutters.

I’ve uploaded a prototype, if you want to see it for yourself.

And here the Camera Script:

public class CameraController : MonoBehaviour {

    public GameObject Target;

    [Header("Mouse Sensetivity")]
    public float sensitivityX = 2f;
    public float sensitivityY = 2f;
    public float sensXAiming = 2f;
    public float sensYAiming = 2f;

    public bool aiming = false;

    [Header("Possible Looking Angles")]
    public float minimumY = -60f;
    public float maximumY = 60f;

    [Header("Number of Frames to average")]
    public int frameCounterX = 35;
    public int frameCounterY = 35;

    //Mouse rotation input
    private float rotationX = 0f;
    private float rotationY = 0f;

    //Used to calculate the rotation of this object
    private Quaternion xQuaternion;
    private Quaternion yQuaternion;
    private Quaternion originalRotation;

    //Array of rotations to be averaged
    private List<float> rotArrayX = new List<float>();
    private List<float> rotArrayY = new List<float>();

    void Start () {
        Rigidbody rb = GetComponent<Rigidbody>();
        if (rb)
            rb.freezeRotation = true;

        originalRotation = transform.localRotation;
        Cursor.lockState = CursorLockMode.Locked;
    }
   
    // Update is called once per frame
    void Update () {

        RotateCamera();
        FollowTarget();

    }

    void FollowTarget()
    {
        GetComponent<Rigidbody>().MovePosition(
            new Vector3(
                Target.transform.position.x,
                Target.transform.position.y + Target.GetComponent<CharacterControllerCustom>().hNormal / 2,
                Target.transform.position.z) - transform.forward * 0.25f
                );
    }

    void RotateCamera()
    {
        //Average rotationX for smooth mouselook
        float rotAverageX = 0f;

        if (!aiming)
            rotationX += Input.GetAxis("Mouse X") * sensitivityX;
        else
            rotationX += Input.GetAxis("Mouse X") * sensXAiming;


        //Add the current rotation to the array, at the last position
        rotArrayX.Add(rotationX);

        //Reached max number of steps?  Remove the oldest rotation from the array
        if (rotArrayX.Count >= frameCounterX)
        {
            rotArrayX.RemoveAt(0);
        }

        //Add all of these rotations together
        for (int i_counterX = 0; i_counterX < rotArrayX.Count; i_counterX++)
        {
            //Loop through the array
            rotAverageX += rotArrayX[i_counterX];
        }

        //Now divide by the number of rotations by the number of elements to get the average
        rotAverageX /= rotArrayX.Count;

        //Average rotationY, same process as above
        float rotAverageY = 0;
        if (!aiming)
            rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
        else
            rotationY += Input.GetAxis("Mouse Y") * sensYAiming;
        rotationY = ClampAngle(rotationY, minimumY, maximumY);
        rotArrayY.Add(rotationY);

        if (rotArrayY.Count >= frameCounterY)
            rotArrayY.RemoveAt(0);

        for (int i_counterY = 0; i_counterY < rotArrayY.Count; i_counterY++)
            rotAverageY += rotArrayY[i_counterY];


        rotAverageY /= rotArrayY.Count;

        //Apply and rotate this object
        xQuaternion = Quaternion.AngleAxis(rotAverageX, Vector3.up);
        yQuaternion = Quaternion.AngleAxis(rotAverageY, Vector3.left);

        transform.localRotation = originalRotation * xQuaternion * yQuaternion;
    }

    private float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360f)
            angle += 360f;

        if (angle > 360f)
            angle -= 360f;

        return Mathf.Clamp(angle, min, max);
    }
}

I’m using Unity version 5.5.0f3 at the moment.

Any idea what i’m doing wrong?

I tried the link and everything works perfectly. Only thing I can think of is that you don’t have enough RAM, but on my end it works great.

Camera stutter usually happens because of mixing Update and FixedUpdate methods on the target and the camera. Those two functions have different call rate, as the first one is called every frame, and the second one is called only on physic ticks. Try changing the Update method to the FixedUpdate one.

If the effect doesn’t suit you, the camera updates can be also lerped in the Update method for more fluid movement of the camera.

Really? Have you tried moving around a cube and looking at it the whole time, because that is where you see the camera stutter best.

Edit: Also i’ve got 8GB RAM, that should be enough right?

Edit2:

Thanks, this actually solves my original problem. But the mouse-smoothing function runs now alot slower, which doesnt work for the game-style im aiming for. (Is there another way to fix it, but keep it at the same speed?)

Yes. Moving RotateCamera() call from the FixedUpdate to the Update method should help.

Doing that brings back the stuttering. :frowning:

Why would you think that? Genuine question.

@Goonomi Just put all camera control to LateUpdate() and it should work (didn’t check the proto, but i’m 99% sure)

Sometimes stutters are caused by insufficient RAM, but it’s probably not the issue here as the game is very simple. I put my camera in the same update I’m moving it. For example, if I’m moving in FixedUpdate(), I’ll put the camera in FixedUpdate() etc… I’ve had jerky cameras before with LateUpdate() so I found that syncing the camera’s update with the movement’s update is best for me.

This results in the same stuttering like normal Update().

Edit:

This is what i’m doing right now, but it still stutters.

Well that is demotivating. How am i supposed to ever finish a game, if i cant even fix such a small issue in the very basic prototype? :frowning:

You have two options, either modify the RotateCamera method to work well in FixedUpdate method, or implement camera interpolation, which removes stutter problems related to mixing Update / FixedUpdate movement.

An example of camera interpolation can be found at http://wiki.unity3d.com/index.php/SmoothFollow2

Try using LateUpdate(). Also, check to see if this is only happening in the editor. I’ve seen issues like this which happened in the editor, but not with a build of the game.

I build it and ran it, but it kept stuttering (like in the WebGL projekt).

How would i modify the RotateCamera method to work? It just gets called not often enough. The second point sounds interesting. Do you have some sort of simple example (i am not that good in programming even though i have 2 years of experience now) that i can adapt for my project?

Edit: sorry for the double post. :frowning: