How do I fix jitter?

So I’m currently making a rigidbody fps controller and I’m getting this jitter that comes in spurts. It’s not horrible but becomes very bad when switching to slow motion. The jitter only happens when I’m walking around and looking at an object. The player is already interpolated as well.

Here’s my player script:

public class PlayerController : MonoBehaviour
{
    //Components
    private Animator anim;
    private Rigidbody rb;

    //Movement
    Vector3 movement;

    //Speed and Sprinting
    private bool sprinting;
    private float speed;
    public float sprintSpeed = 750f;
    public float walkSpeed = 500f;
    public float stamina, maxStamina;
    public bool usingStamina;

    //Jump and Grouncheck
    public float jumpForce;
    public bool isGrounded;
    public Transform groundCheck;
    public float groundDistance = 0.4f;
    public LayerMask whatIsGround;
    
    public Vector3 airControl;
    public float airControlForce;

  



    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
        anim = GetComponent<Animator>();
       
    }

    // Update is called once per frame
    void Update()
    {
        movement.x = Input.GetAxisRaw("Horizontal") ;
        movement.z = Input.GetAxisRaw("Vertical");

        movement.Normalize();

        isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, whatIsGround);
           
        if (isGrounded)
        {
            Jump();
        }

        Sprint();
           
    }

    private void FixedUpdate()
    {


        if (isGrounded)
        {

            rb.velocity = rb.rotation * new Vector3(movement.x * speed * Time.deltaTime, rb.velocity.y, movement.z * speed * Time.deltaTime);
      
        }
                    
       if (!isGrounded)
        {

            rb.AddRelativeForce(movement.x * airControlForce, 0f, movement.z * airControlForce);
    
        }
  
    }

    private void Jump()
    {

        if (Input.GetKeyDown(KeyCode.Space))
        {
            rb.AddForce(jumpForce * transform.up);
        }
      
    }

    private void Sprint()
    {
        speed = walkSpeed;

        if (isGrounded)
        {
            if(Input.GetKeyDown(KeyCode.LeftShift))
            {

                sprinting = true;

            }
                        
        }

        if (Input.GetKeyUp(KeyCode.LeftShift))
        {

            sprinting = false;

        }

       if(usingStamina)
        {
            if (sprinting && stamina >= 0f)
            {
                speed = sprintSpeed;
                stamina -= Time.deltaTime;
            }
            else if (!sprinting && stamina < maxStamina)
            {
                stamina += Time.deltaTime;
            }
        }
       else if(sprinting)
        {
            speed = sprintSpeed;
        }
    
    }
   
    private void OnDrawGizmos()
    {
        Gizmos.DrawWireSphere(groundCheck.position, groundDistance);
    }

}

And here’s my camera script:

public class CameraController : MonoBehaviour
{
    public Vector2 mouseLook;
    [Range(0.0f, 100f)]
    public float sensitivity;

    private GameObject character;
    private Rigidbody rb;
    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
        character = transform.parent.gameObject;
        rb = character.GetComponent<Rigidbody>();
    }

    private void LateUpdate()
    {
        mouseLook.x += Input.GetAxis("Mouse X") * sensitivity;
        mouseLook.y += Input.GetAxis("Mouse Y") * sensitivity;
        mouseLook.y = Mathf.Clamp(mouseLook.y, -90f, 90f);


        transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);
        rb.MoveRotation(Quaternion.AngleAxis(mouseLook.x, rb.transform.up));
    }


}

I’m going to assume it has something to do with updates vs fixed updates but I can’t figure out what I did wrong.

###Edit
Wait a second, I overlooked that this is a first person camera. LateUpdate (as well as Update, by the way) should work fine. However, you are mixing camera controls with controls for the rigidbody.

Rigidbody interpolation means that between two FixedUpdates, the object is interpolated between the second latest FixedUpdate result and the latest. So if you had, say, ~3 frames between two FixedUpdates (which is what you have at 144 fps), the object moves in 3 steps from the previous position to the current one.

Now, if you were to interfere in that interpolation by doing stuff with the rigidbody, I could imagine that things could get hairy. Although you’re doing movement in FixedUpdate and only rotation in Update, I could, for example, imagine that rotation interpolation could get into conflict with rotation applied in Update.

Original answer

Here, have this article: What exactly is FixedUpdate? – 13Pixels Blog

In it, there’s a script linked that you can use: Interpolates a GameObject's position and rotation while being updated in FixedUpdate. · GitHub

In short: Move the camera in FixedUpdate as well and interpolate it with that script. If you still get jitter, interpolate your rigidbody with that script as well (and turn interpolation off on the rb itself).