Jitter while rotating Rigidbody based FPS controller

Hello. I’m working on a player controller for a first person shooter, based on a Rigidbody.

I wrote a script to handle mouse look, and I attached it to the Rigidbody. The first person camera is a child of the Rigidbody. The scripts holds a reference to the Transform of the camera object. Below there’s a picture showing the hierarchy, where Player holds the Rigidbody:

7882615--1002844--upload_2022-2-9_15-40-33.png

While rotating the Rigidbody by its up vector, the camera’s view jitters. Rotating the camera by its right vector doesn’t cause any jitter. Keep in mind that interpolation is enabled for the Rigidbody, as shown below:

7882615--1002850--upload_2022-2-9_15-43-17.png

Here’s an abstract of my scritp, where body is the player’s Rigidbody and firstPersonCamera is the camera’s Transform:

    // Update is called once per frame.
    void Update() {
        UpdateMouseLook();
    }

    // It updates player's view, given mouse's input.
    private void UpdateMouseLook() {
        // Update mouseDelta, eventually damping it
        Vector2 targetMouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
        mouseDelta = Vector2.SmoothDamp(mouseDelta, targetMouseDelta, ref mouseDeltaDamp, mouseSmoothness);

        // Update pitch and roll
        cameraPitch += (invertYAxis ? mouseDelta.y : -mouseDelta.y) * mouseSensitivity;
        cameraPitch = Mathf.Clamp(cameraPitch, -90f, 90f);
        cameraYaw += (invertXAxis ? -mouseDelta.x : mouseDelta.x) * mouseSensitivity;
        cameraYaw %= 360f;

        // Apply rotations
        firstPersonCamera.localEulerAngles = Vector3.right * cameraPitch;
        body.MoveRotation(Quaternion.Euler(0f, cameraYaw, 0f));
        // Note: deltaTime isn't used here since mouseDelta is sufficient.
    }

Previously, I moved the camera away from Player’s hierarchy. I handled their rotation separately, and that solved the jittering issue. The problem is I wish to keep the hierarchy simple and intuitive, as showed above, but I couldn’t find a solution for this jitter.

I tried to move the UpdateMouseLook call in FixedUpdate with very bad results. I also tried to move the last MoveRotation call in FixedUpdate, worsening the jitter. I also tried to build the project and running it from the executable, but the jittering was still there.

Any ideas on how to solve the jittering? Thanks in advance.

The unique solution I know is to make the camera not parented to the player, and make the camera rotate in his own. In the karlson movement tutorial Dani said that parenting the camera to the player will cause jitter, and another guy I saw said the same.
So, you will have to unparent the camera and make some script that moves the camera to the corresponding position.

Thanks for the reply.

Yeah, I opted for that solution in the end, solving the jitter. I wish there was a cleaner method though.

Fun fact, Im doing the same.
My solution to make it cleaner was this hierarchy:

PlayerContainer(To make prefab)
-Player(Rigidbody and collisions)
-Other stuff…
-Camera(This one is the one that rotates)
-Main camera
-More stuff…(Guns)

That way, if you make crouching by scaling the player down, the guns will not scale down, this works fine to me.

Also, as a plus, if you have the classic problem of guns getting stuck in a wall here is the solution:

-Add a layer called something like “Gun” or “Weapon”
-Make the camera dont render that layer.
-Add another camera child of the actual main camera, I ussualy call it “Gun cam”
-In the clear flags change it to “depth only”
-Make it only render the “Gun” layer (or whatever you called it)
-Finally put the depth value higher than the main camera (By default it will have 0 so setting it to 1 is enough.
-Now you can add all the guns you want (make them child of the gun cam)

Hope I helped you :stuck_out_tongue:

Thanks for the tips!

In regards of crouching, by changing the height (and the center) of the Collider you don’t have to resize the actual GameObject’s Transform. You should give a look at the character controller script in Unity’s official FPS Microgame, which does exactly that.