Player vibrates back and forth when moving

Hello,
I’ve tried creating a new project on Unity3D but I’ve noticed that whenever I move my player after a while, it starts vibrating back and forth. I’ve been using a different type of Cinemachine Camera (Virtual Camera, I’ll give more details if this can cause the problem) and suddenly that happens. Here’s the code that manages Player Movement
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    [Header("Object References")]
    public CharacterController controller;
    public new Camera camera;
    public Animator animator;

    [Header("Variables")]
    public float walkingSpeed = 5f;
    public float sprintSpeed = 10f;
    public float turnTime = 0.13f;
    private float currentSpeed;
    private float turnVelocity;

    [Header("Variables (Read-Only)")]
    public float verticalSpeed = 0f;
    public const float gravityConstant = 9.81f;

    public enum State
    {
        Idle = 0,
        Running = 1,
        Jumping = 2
    }

    private void Start()
    {
        camera = Camera.main;
        currentSpeed = walkingSpeed;
    }

    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.LeftShift))
        {
            currentSpeed = sprintSpeed;
        }
        if(Input.GetKeyUp(KeyCode.LeftShift))
        {
            currentSpeed = walkingSpeed;
        }
    }

    void FixedUpdate()
    {
        float horizontal = Input.GetAxisRaw("Horizontal");
        float vertical = Input.GetAxisRaw("Vertical");
        Vector3 moveDir = new Vector3(horizontal, 0f, vertical).normalized;

        /*
         * TODO: TRANSFER SPEED, RUNNING AND GRAVITY METHODS/VARIABLES TO 
         * TEMPLATE FOR OTHER CHARACTERS (ENEMIES AS WELL)
         */


        if(moveDir.magnitude >= 0.1)
        {

            float targetAngle = Mathf.Atan2(moveDir.x, moveDir.z) * Mathf.Rad2Deg + camera.transform.eulerAngles.y;
            float finalAngle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnVelocity, turnTime);
            transform.rotation = Quaternion.Euler(0f, finalAngle, 0f);

            Vector3 finalMoveDir = Quaternion.Euler(0f, targetAngle, 0f).normalized * Vector3.forward;
            controller.Move(finalMoveDir * currentSpeed * Time.deltaTime);
            animator.SetInteger("State", (int)State.Running);
        }
        else
        {
            animator.SetInteger("State", (int)State.Idle);
        }
        applyGravity();
    }

    //GRAVITY HANDLER
    public void applyGravity()
    {
        switch(controller.isGrounded)
        {
            case true:
                verticalSpeed = 0f;
                break;
            case false:
                verticalSpeed -= gravityConstant * Time.deltaTime;
                break;
        }

        Vector3 gravityDir = new Vector3(0f, verticalSpeed, 0f);
        controller.Move(gravityDir * Time.deltaTime);

    }
}

This is the part that actually does the moving:

   void FixedUpdate()
    {
        float horizontal = Input.GetAxisRaw("Horizontal");
        float vertical = Input.GetAxisRaw("Vertical");
        Vector3 moveDir = new Vector3(horizontal, 0f, vertical).normalized;

        /*
         * TODO: TRANSFER SPEED, RUNNING AND GRAVITY METHODS/VARIABLES TO 
         * TEMPLATE FOR OTHER CHARACTERS (ENEMIES AS WELL)
         */


        if(moveDir.magnitude >= 0.1)
        {

            float targetAngle = Mathf.Atan2(moveDir.x, moveDir.z) * Mathf.Rad2Deg + camera.transform.eulerAngles.y;
            float finalAngle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnVelocity, turnTime);
            transform.rotation = Quaternion.Euler(0f, finalAngle, 0f);

            Vector3 finalMoveDir = Quaternion.Euler(0f, targetAngle, 0f).normalized * Vector3.forward;
            controller.Move(finalMoveDir * currentSpeed * Time.deltaTime);
            animator.SetInteger("State", (int)State.Running);
        }
        else
        {
            animator.SetInteger("State", (int)State.Idle);
        }
        applyGravity();
    }

I think you’re calling Controller.Move TWICE in the same fixedupdate frame. Once at Line 64 in FixedUpdate, and again at line 88 in applyGravity().

So a couple of things… first, you might want to combine both of these moves into a single move at the end by taking your finalMoveDir and combining it with the gravityDir from applyGravity, and THEN calling the controller.Move(), because each call of controller.Move() takes collisions into account.

Second, I believe that controller.Move is meant to be applied in the Update() event rather than FixedUpdate() event. (at least most Unity Examples that I’ve seen indicate this)

I’ve solved the initial problem about the camera, I’ve changed the cinemachine camera type to FreeLook instead of Virtual. However, I’ve tried implementing what you said but now whenever I press the key to jump, the player only jumps “randomly”: even if I start the project and completely stand still, if I press space 6 times the player only jump a couple of times. I tried removing the controller.isGrounded and it works (but of course, the player can jump even in mid-air, but at least the rest of the code is working). Here’s my current code:
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    [Header("Object References")]
    public CharacterController controller;
    public new Camera camera;
    public Animator animator;

    [Header("Variables")]
    public float walkingSpeed = 5f;
    public float sprintSpeed = 10f;
    public float turnTime = 0.13f;
    public float jumpForce = 6f;
    public State currentState;
    private Vector3 finalMoveDir;
    //VARIABLES THAT TRACK CURRENT VALUES
    private float currentJumpForce = 0f;
    private float currentSpeed;
    private float turnVelocity;

    public enum State
    {
        Idle = 0,
        Running = 1,
        Jumping = 2
    }

    private void Start()
    {
        camera = Camera.main;
        currentSpeed = walkingSpeed;
    }

    void Update()
    {
        //HANDLE INPUT
        if(Input.GetKeyDown(KeyCode.LeftShift))
        {
            currentSpeed = sprintSpeed;
        }
        if(Input.GetKeyUp(KeyCode.LeftShift))
        {
            currentSpeed = walkingSpeed;
        }
        if(Input.GetKeyDown(KeyCode.Space) && controller.isGrounded)
        {
            currentJumpForce = jumpForce;
        }

        //APPLY FORCES
        float horizontal = Input.GetAxisRaw("Horizontal");
        float vertical = Input.GetAxisRaw("Vertical");
        Vector3 moveDir = new Vector3(horizontal, 0f, vertical).normalized;
        Vector3 jumpDir = new Vector3(0f, currentJumpForce, 0f);

        if(moveDir.magnitude >= 0.1)
        {

            float targetAngle = Mathf.Atan2(moveDir.x, moveDir.z) * Mathf.Rad2Deg + camera.transform.eulerAngles.y;
            float finalAngle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnVelocity, turnTime);
            transform.rotation = Quaternion.Euler(0f, finalAngle, 0f);

            finalMoveDir = Quaternion.Euler(0f, targetAngle, 0f).normalized * Vector3.forward;
            SetState(State.Running);
        }
        else
        {
            switch(currentJumpForce > 0.1f)
            {
                case true:
                    SetState(State.Jumping);
                    break;
                default:
                    SetState(State.Idle);
                    break;
            }
        }

        controller.Move((finalMoveDir * currentSpeed * Time.deltaTime) + jumpDir);
        finalMoveDir = new Vector3(0f, 0f, 0f);
        currentJumpForce = 0f;
    }

    public void SetState(State state)
    {
        animator.SetInteger("State", (int)state);
        currentState = state;
    }

}