Smoother Turning (New guy here, hi)

So I’m learning from scratch working on my first little project. I started learning C# as my first language this week.

I’m a stickler for smooth gameplay and character controls.

I’ve worked my way through a simple movement trying to learn as I go so there’s a lot of notes, apologies.

Video of Movement

I have an issue when my guy turns he jitters quite bad when you press the left and right keys is there any way to smooth this out. I had been thinking of Lerp or Quartonian rotations but I’m unsure of usage.

Here’s my code, I’m trying to keep it as neat as possible:

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

public class Character : MonoBehaviour
{

    // Making Spped a variable and declaring that we are using the Character controller component. Naming it controller
    public float RotationSpeed = 240.0f;
    public float Speed;
    [SerializeField] private Transform groundChecker = null;
    [SerializeField] private LayerMask playerMask;
    //Movment Speed Calls
    [SerializeField] private float moveSpeed;
    [SerializeField] private float walkSpeed;
    [SerializeField] private float runSpeed;


    private CharacterController controller;
    private bool groundedPlayer;
    private float jumpHeight = 0.75f;
    private float gravityValue = -9.81f;
    // creating the Vector 3 player velocity, 
    private Vector3 playerVelocity;



    // Start is called before the first frame update
    void Start()
    {
        //At startup telling the script that we are using the Character controller component
        controller = GetComponent<CharacterController>();

    }

    // Update is called once per frame
    void Update()
    {

        // -------- GRAVITY --------
        // && statement asks if BOTH values are true for output.
        // .isGrounded is a built in unity statement similar to bool collison check.
        // groundedPlayer = controller.isGrounded; DO NOT USE THE IS GROUNDED SETTING BECAUSE IT IS BUGGED
        // (IT WONT JUMP WHEN YOU WANT IT TO) use the CheckSphere method for consistent results.

        //manually detecting isGrounded with physics checksphere, Checksphere is a Bool variable.
        // groundChecker is a private variable which is the Child empty of the player at feet.
        // groundDistance is a private float radius of the sphere

        float checkerRadius = 0.1f;
        groundedPlayer = Physics.CheckSphere(groundChecker.position, checkerRadius, playerMask);

        if(groundedPlayer && playerVelocity.y < 0)
        {
            // we set the player velocity to 0 so that it doesn't carry over gravity & velocity creating undesirable results.
            playerVelocity.y = 0f;
        }

        // -------- Movement --------
        // Declaring that we are creating a Vector3 based move operation using the Unity axis inputs, We change y to zero because we do not want to go up in 3d space. if this was a 2d game we would use only x and y.
        // Smoothed by GetAxis rather than GetAxisRaw.
        Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

        //Walk/Run funcitons
        // A mixture of variables asking if we are moving and holding left shift.

        //Run

        if (move != Vector3.zero && !Input.GetKey(KeyCode.LeftShift))
        {
            walk();
        }
        else if (move != Vector3.zero && Input.GetKey(KeyCode.LeftShift))
        {
            run();
        }
        else if (move == Vector3.zero)
        {
            idle();
        }
        // MOVEMENT VARIABLES

        void idle()
        {

        }

        void walk()
        {
            moveSpeed = walkSpeed;
        }

        void run()
        {
            moveSpeed = runSpeed;
        }

        move *= moveSpeed;


        // Telling the controller move operation that it's independant of framerate and to use our speed variable
        controller.Move(move * Time.deltaTime * Speed);
        // If the player not currently moving with Vector3 zero then wherever its moving the most is facing.
        if (move != Vector3.zero)
            transform.forward = move;

        // ------- FOR JUMPING --------

    // If jump is pressed
        if (Input.GetButtonDown("Jump") && groundedPlayer)
        {
            //Assuming .y of vector3 playervelocity above. Mathf is a generic math command ending with a float value
            // Jumpheight is set by us (1)
            // * -3f * -9.81 = 29.43
            //Mathf.Sqrt roots this for a jump value of ~5.42. This is named as PlayerVelocity.y when jump is pressed
            playerVelocity.y += Mathf.Sqrt(jumpHeight * -2.0f * gravityValue);
        }
        // We then use +=
        // x = 7   # assigns the value, 7, to x
        // x += 4  # adds 4 to 7, and assigns the result, 11, to x

        // So Playervelocity.y = (Above equation = 5.42) += -9.81 = -4.41 * TimeDelta
        playerVelocity.y += gravityValue * Time.deltaTime;
        controller.Move(playerVelocity * Time.deltaTime);
    }
}

transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(-move),RotationSpeed);

Quaternion.Slerp is what you want as you mentioned. It takes 3 parameters. The first one is the current rotation. The second is the new rotation and the last one is the speed between 0-1 for rotating.

The Quaternion.LookRotation will return a Quaternion direction based on your Vector3 movement direction.

So the above says that you want to rotate from your current transform rotation to the look rotation of the move vector and you want to do it at the rotation speed. (I find 0.05f is smooth for me for rotation speed).

One thing to note is that I have a negative sign for the move. You might not need that. So if your character is rotating the wrong way just take that out