Unity camera is jittering, janky and problematic

Now i have the EXACT same issue as this user:

https://www.youtube.com/watch?v=faY50bf4oWs

If you go to 0:42 you can see that the camera jumps over interactable objects and all in all is janky and stuttering.

How can one fix this issue?

This is my camera code, and its the only code that affects the camera. (The camera is a child of the player object tho)

[SerializeField] float Sens;
  public Transform camtransform;

  float xRot = 0f;
  public float xMouse;
  public float yMouse;

  private void Start()
  {
      Cursor.lockState = CursorLockMode.Locked;
      Sens = 180f;
  }

  void Update()
  {

      xMouse = Input.GetAxis("Mouse X") * Sens * Time.smoothDeltaTime;
      yMouse = Input.GetAxis("Mouse Y") * Sens * Time.smoothDeltaTime;

      xRot -= yMouse;
      xRot = Mathf.Clamp(xRot, -90f, 90f);

      
      transform.localRotation = Quaternion.Euler(xRot, 0, 0);
      camtransform.Rotate(Vector3.up * xMouse);

  }

Well I can tell you that if your camera is the child of the player object and the player object is moving in any way then the code you posted is not the only code that affects the camera :wink:

Without watching the video I can probably guess that itā€™s likely they parented their camera to the player object which is controlled by physics. Thatā€™s a pretty big no-no if you want your camera to operate smoothly as anything using physics will be controlled in discrete timesteps that just about never match the framerate of your game.

Instead, you want your camera to be completely separate from the object it is tracking and use code only to calculate the position and orientation it should be. Admittedly, this is a rather advanced topic and it can take a long time to really master the knowledge and math needed to do that well. So Iā€™ll take a page out of Kurtā€™s book and suggest you look into installing Unityā€™s Cinemachine package which apparently has tools to do this all for you (I assume because thatā€™s what Iā€™ve been told. I havenā€™t actually used it myself in years).

Hereā€™s a link to help get you started: https://unity.com/features/cinemachine

You should remove the Time.smoothDeltaTime from lines 17 and 18. The mouse isnā€™t effected by frame rate.

Line 25 is strange in that it seems to be rotating the camera ā€˜camtransformā€™ around the Y axis but normally we rotate the character around the Y axis and the camera around the X axis. This is assuming the camera is a child of the player.

Youā€™re not showing us the script that actually moves/translates the player. Youā€™re only showing the script that rotates and so it could be the movement script thatā€™s jittery.

I realized I probably should actually explain better how to make this work rather than simply saying ā€œUse this package that magically does stuff for youā€.

First thing: The easy stuff - sorta. The reason you have jittery movement is likely due to the fact that your camera is the child of another object that Iā€™m guessing is controlled by physics. As I said above, this can cause issues due to the slower tick rate of the physics system but if you make the physics rigidbody use interpolation that jittery motion can be greatly smoothed. Itā€™s still not the best approach but it can be used for a quick and dirty method. Eventually youā€™ll discover why seperating your camera and using a script that allows it to smoothly follow an object is better but sometimes the best lessons come from experience so if setting the rigidbody to interpolate motion works then stick with it for now and donā€™t worry about it until it becomes a problem again. Just keep this bit of advice in mind for later when you hit that wall so you know what to start researching next.

As for the look math. It seems really off. For starters , you have some weird names. Instead of xRot and yRot Iā€™d suggest using the terms Pitch and Yaw since they are pretty standard and wonā€™t be confused with logic like xMouse = yRot and yMouse = xRot.

Next, you are caching the wrong information. You want to cache the Pitch and Yaw, not the xMouse and yMouse. Those values are temporary and only used as inputs for the current frameā€™s mouse delta. The pitch and yaw on the other hand need to be tracked every frame since they are the absolute values. So get rid of the xMouse and yMouse declarations at the top and make them local variables. Where you adjust and assign the yaw (named xRot in your case) you also want to add xMouse to the Yaw (which you donā€™t have anywhere).

Finally, you are transforming the data twice in a way that will causeā€¦ issues I imagine. It would be much better to remove the Rotate() call to the transform and simply set both values directly in the localRotation. No worry of overwriting data and no less worry of gimbal lock. In this case after you assign Yaw and Pitch you can pass both of them to the Quaternion that you assign to the local rotation and you are all done.

As a small nitpick I noticed you also set the value of sens in the start method. Doing this just overwrites whatever value you set in the inspector. If you want a default value just assign it directly inline when you declare the variable.

EDIT: Made a small adjustment for clarity to future readers hopefully.

1 Like