rigidbody first person camera judder

so I’m trying to create a first-person character with a rigid body. I need a rigid body because I want a game with multiple gravity sources and in order to do that I need to be able to rotate the character and a character controller cannot do that.

The problem I now face is that it looks like the game is in low fps when I move. in scene view I can see that my characters move smoothly. so I think that it has nothing to do with the movement but something with the camera.

I also compared the movement with that form a character controller and the character controller does not have this problem.

does someone know a fix for this?

here is my code:

the script for moving the camera:

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

public class MouseLook : MonoBehaviour
{
    public float mouseSensitivity = 100f;

    public Transform playerBody;

    float xRotation = 0f;

    // Start is called before the first frame update
    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
        float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;

        xRotation -= mouseY;
        xRotation = Mathf.Clamp(xRotation, -90f, 90f);


        transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
        playerBody.Rotate(Vector3.up * mouseX);

    }
}

in case needed here is my code for moving my character.

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

public class characterController : MonoBehaviour
{
    public float speed = 10.0f;
    public Rigidbody rb;
    public LayerMask groundLayers;

    public float jumpForce = 7;
    public CapsuleCollider col;

    float transelation;
    float straffe;

    // Start is called before the first frame update
    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
        rb = this.GetComponent<Rigidbody>();
        col = GetComponent<CapsuleCollider>();
    }

    // Update is called once per frame
    void Update()
    {
        transelation = Input.GetAxis("Vertical") * speed;
        straffe = Input.GetAxis("Horizontal") * speed;
        bool jumping = Input.GetKeyDown(KeyCode.Space);
     

        transelation *= Time.smoothDeltaTime;
        straffe *= Time.smoothDeltaTime;



        if (IsGrounded())
        {
            rb.useGravity = false;
        }else
        {
            rb.useGravity = true;
        }
    

        if (IsGrounded() && Input.GetKeyDown(KeyCode.Space))
        {
            rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
        }

        if (Input.GetKeyDown("escape"))
        {
            Cursor.lockState = CursorLockMode.None;
        }


    }

   void FixedUpdate(
  {
       transform.Translate(straffe, 0, transelation);
  }

    private bool IsGrounded()
    {
        return Physics.CheckCapsule(col.bounds.center, new Vector3(col.bounds.center.x, col.bounds.min.y, col.bounds.center.z), col.radius * .9f, groundLayers);
    }
}

Try changing the FixedUpdate() function in your follow code to be something like public void MyUpdate() and then explicitly calling it from your movement script (by reference) after you have moved and rotated.

Also, you are doing Rigidbody stuff in Update()… it’s always best to do Physics in FixedUpdate() and this can sometimes lead to juddering if you mix-and-match.

I tried your suggestions but its did not help.