Need to change Rigidbody player to Character Controller.

Several reasons why I am abandoning Rigidbody Character Controller, but one of the main ones is I grew tired of fighting with step detection. What I need help with is minor but I can’t find any guidance to restrict some movement on the Character controller to keep it from completely turning around when using the WASD or Arrow Keys. I also need to be able to properly toggle on/off Run better than I currently have it.

Here is the script I am converting to. There is a note next to what I am trying to resolve:

using System;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    private Animator anim;
    private CharacterController cc;
    public Vector2 inputNormalized;
  
    [Header("Movement")]
    public bool steer;
    public float gravity = -9.10f;
    [Range(0, 10)] public float jH = 1f;

    public float moveSpeed;
    [Range(0, 10)] public float runSpeed;
    public float rotSpeed;
    public float jumpSpeed;
    public float jumpButtonGracePeriod;

    private float ySpeed;
    private float originalStepOffset;
    private float? lastGroundedTime;
    private float? jumpButtonPressedTime;

    public bool isRunning;


    public void Start()
    {
        CameraControl cameraControl = FindObjectOfType<CameraControl>();
        cameraControl.Init();
    }
    // Start is called before the first frame update
    private void Awake()
    {
        cc = GetComponent<CharacterController>();
        anim = GetComponent<Animator>();
        originalStepOffset = cc.stepOffset;
    }

    // Update is called once per frame
    private void Update()
    {
        Move();
    }
    private void Move()
    {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");// I belive this is where I need something for (< 0 ? -input.x : input.x ) as it is in a rigidbody setup but cannot sort out the equvilant in a Character Controller;
      
        Vector3 movementDirection = new Vector3(x, 0, z);
        float magnitude = Mathf.Clamp01(movementDirection.magnitude) * moveSpeed;
        movementDirection.Normalize();

        cc.SimpleMove(movementDirection * magnitude);

        if (movementDirection != Vector3.zero)
        {
            Quaternion toRotation = Quaternion.LookRotation(movementDirection, Vector3.up);
            transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotSpeed * Time.deltaTime);
        }
//for the running I have at present this, but am asking for some suggestions to make it transition better as I dont want to use the hold down shift key. 

        if (Input.GetButtonDown("Run"))
        {
            isRunning = !isRunning;
        }
        if (isRunning)
        {
            moveSpeed = runSpeed;
;
        }
        else
        {
            moveSpeed = 0.5f;

        }

        ySpeed += Physics.gravity.y * Time.deltaTime;

        if (cc.isGrounded)
        {
            lastGroundedTime = Time.time;
        }

        if (Input.GetButtonDown("Jump"))
        {
            jumpButtonPressedTime = Time.time;
        }

        if (Time.time - lastGroundedTime <= jumpButtonGracePeriod)
        {
            cc.stepOffset = originalStepOffset;
            ySpeed = -0.5f;

            if (Time.time - jumpButtonPressedTime <= jumpButtonGracePeriod)
            {
                ySpeed = jumpSpeed;
                jumpButtonPressedTime = null;
                lastGroundedTime = null;
            }
        }
        else
        {
            cc.stepOffset = 0;
        }

        Vector3 velocity = movementDirection * magnitude;
        velocity.y = ySpeed;

        cc.Move(velocity * Time.deltaTime);

        if (movementDirection != Vector3.zero)
        {
            anim.SetBool("IsMoving", true);
            Quaternion toRotation = Quaternion.LookRotation(movementDirection, Vector3.up);

            transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotSpeed * Time.deltaTime);
        }
        else
        {
            anim.SetBool("IsMoving", false);
        }
    }
      
}

The Camera that needs a little refinement is:

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

public class CameraControl : MonoBehaviour
{
    // NOTE:Been also having issues with collission detection to prevent camera from passing through other mesh/objects such as ground
    // and getting Smoothing to work properly when using camera tpo steer player.

    //Inputs

    KeyCode leftMouse = KeyCode.Mouse0;
    KeyCode rightMouse = KeyCode.Mouse1;
    KeyCode middleMouse = KeyCode.Mouse2;

    public CameraState cameraState = CameraState.CameraNone;
    public CameraMoveState camMoveState = CameraMoveState.OnlyWhileMoving;
    public float cameraAdjustSpeed = 1;


    [SerializeField] [Range(0, 25)] float camMaxDistance;
    [SerializeField] [Range(0, 10)] float camHeight;

    [SerializeField] [Range(-90, 90)] float camMaxTilt, camMinTilt;
    [SerializeField] [Range(0, 100)] float camSpeed;


    [SerializeField] [Range(0, 300)] float scrollSpeed;
    [SerializeField] [Range(0, 10)] float scrollMax;

    [SerializeField] [Range(0, 10)] float currentTilt, currentPan, currentDistance;

    //Collision

    public bool collisionDebug;
    public float collisionCushion = 0.35f;
    public float clipCushion = 1.5f;
    public int rayGridX = 9, rayGridY = 5;
    [SerializeField] float adjustedDistance;


    Vector3[] camClip, clipDirection, playerClip, rayColOrigin, rayColPoint;
    bool[] rayColHit;
    Ray camRay;
    RaycastHit camRayHit;

    //CameraSmoothing //Doesn't work as of yet and haven't sorted out why.

    [SerializeField] float panAngle, panOffset;
    bool camXAdjust, camYAdjust;
    [SerializeField] float rotationXCushion = 3, rotationXSpeed = 0;
    [SerializeField] float yRotMin = 0, yRotMax = 20, rotationYSpeed = 0;

    //Reference

    PlayerController player;
    public Transform tilt;
    Camera mainCam;

 
    // Update is called once per frame
    public void Init()
    {
        player = FindObjectOfType<PlayerController>();
        mainCam = Camera.main;

        transform.position = player.transform.position + Vector3.up * camHeight;
        transform.rotation = player.transform.rotation;

        tilt.eulerAngles = new Vector3(currentTilt, transform.eulerAngles.y, transform.eulerAngles.z);
        mainCam.transform.position += tilt.forward * -currentDistance;
    }

    void Update()
    {
        if (!Input.GetKey(leftMouse) && !Input.GetKey(rightMouse) && !Input.GetKey(middleMouse))
            cameraState = CameraState.CameraNone;
        else if (Input.GetKey(rightMouse))
            cameraState = CameraState.CameraRotate;
        else if (!Input.GetKey(leftMouse) && Input.GetKey(rightMouse) && !Input.GetKey(middleMouse)) //if left mouse button is pressed
            cameraState = CameraState.CameraSteer;

        CameraClipInfo();
        CameraCollisions();
        CameraInputs();
        ScrollCam();
        CameraTransform();
    }
    void LateUpdate()
    {
        panAngle = Vector3.SignedAngle(transform.forward, player.transform.forward, Vector3.up);

        switch (camMoveState)
        {
            case CameraMoveState.OnlyWhileMoving:
                if (player.inputNormalized.magnitude > 0 || player.rotSpeed != 0)
                {
                    CameraXAdjust();
                    CameraYAdjust();
                }
                break;

            case CameraMoveState.OnlyHorizontalWhileMoving:
                if (player.inputNormalized.magnitude > 0 || player.rotSpeed != 0)
                    CameraXAdjust();
                break;

            case CameraMoveState.AlwaysAdjust:
                CameraXAdjust();
                CameraYAdjust();
                break;

            case CameraMoveState.NeverAdjust:
                CameraNeverAdjust();
                break;
        }
    }

 
    void CameraInputs()
    {

        if (cameraState != CameraState.CameraNone)
        {
            if (!camYAdjust && (camMoveState == CameraMoveState.AlwaysAdjust || camMoveState == CameraMoveState.OnlyWhileMoving))
                camYAdjust = true;

            if (cameraState == CameraState.CameraRotate)
                if(!camXAdjust && camMoveState != CameraMoveState.NeverAdjust)
                    camXAdjust = true;
            if (player.steer)
                player.steer = false;

            currentPan += Input.GetAxis("Mouse X") * camSpeed;
         

            currentTilt -= Input.GetAxis("Mouse Y") * camSpeed;
            currentTilt = Mathf.Clamp(currentTilt, camMinTilt, camMaxTilt);

        }
        if (!player.steer)
        {
            Vector3 playerReset = player.transform.eulerAngles;
            playerReset.y = transform.eulerAngles.y;

            player.transform.eulerAngles = playerReset;

            player.steer = true;
        }
     
        //Keyboard & Mouse
        if (Input.GetKey(rightMouse))
        {
            Cursor.visible = false;
            Cursor.lockState = CursorLockMode.Locked;
        }

        else if (Cursor.visible == false)
        {
            Cursor.visible = true;
            Cursor.lockState = CursorLockMode.None;
        }
    }
    public void ScrollCam()
    {
        currentDistance -= Input.GetAxis("Mouse ScrollWheel") * scrollSpeed * Time.deltaTime;
        currentDistance = Mathf.Clamp(currentDistance, 0, scrollMax);
    }

    public void CameraTransform()
    {
        switch (cameraState)
        {
            case CameraState.CameraNone:
                currentPan = currentPan = player.transform.eulerAngles.y;
                currentTilt = 10;
                break;
        }

        transform.position = player.transform.position + Vector3.up * camHeight;
        transform.eulerAngles = new Vector3(transform.eulerAngles.x, currentPan, transform.eulerAngles.z);
        tilt.eulerAngles = new Vector3(currentTilt, transform.eulerAngles.y, transform.eulerAngles.z);
        mainCam.transform.position = transform.position + tilt.forward * -currentDistance;
    }
    void CameraClipInfo()
    {
        camClip = new Vector3[4];

        mainCam.CalculateFrustumCorners(new Rect(0, 0, 1, 1), mainCam.nearClipPlane, Camera.MonoOrStereoscopicEye.Mono, camClip);

        clipDirection = new Vector3[4];
        playerClip = new Vector3[4];

        int rays = rayGridX * rayGridY;

        rayColOrigin = new Vector3[rays];
        rayColPoint = new Vector3[rays];
        rayColHit = new bool[rays];
    }
    void CameraCollisions()
    {
        float camDistance = currentDistance + collisionCushion;

        for (int i = 0; i < camClip.Length; i++)
        {
            Vector3 clipPoint = mainCam.transform.up * camClip[i].y + mainCam.transform.right * camClip[i].x;
            clipPoint *= clipCushion;
            clipPoint += mainCam.transform.forward * camClip[i].z;
            clipPoint += transform.position - (tilt.forward * camMaxDistance);

            Vector3 playerPoint = mainCam.transform.up * camClip[i].y + mainCam.transform.right * camClip[i].x;
            playerPoint += transform.position;

            clipDirection[i] = (clipPoint - playerPoint).normalized;
            playerClip[i] = playerPoint;
        }

        int currentRay = 0;
        bool isColliding = false;

        float rayX = rayGridX - 1;
        float rayY = rayGridY - 1;

        for (int x = 0; x < rayGridX; x++)
        {
            Vector3 CU_Point = Vector3.Lerp(clipDirection[1], clipDirection[2], x / rayX);
            Vector3 CL_Point = Vector3.Lerp(clipDirection[0], clipDirection[3], x / rayX);

            Vector3 PU_Point = Vector3.Lerp(playerClip[1], playerClip[2], x / rayX);
            Vector3 PL_Point = Vector3.Lerp(playerClip[0], playerClip[3], x / rayX);

            for (int y = 0; y < rayGridY; y++)
            {
                camRay.origin = Vector3.Lerp(PU_Point, PL_Point, y / rayY);
                camRay.direction = Vector3.Lerp(CU_Point, CL_Point, y / rayY);
                rayColOrigin[currentRay] = camRay.origin;

                if (Physics.Raycast(camRay, out camRayHit, camDistance))
                {
                    isColliding = true;
                    rayColHit[currentRay] = true;
                    rayColPoint[currentRay] = camRayHit.point;

                    if (collisionDebug)
                    {
                        Debug.DrawLine(camRay.origin, camRayHit.point, Color.cyan);
                        Debug.DrawLine(camRayHit.point, camRay.origin + camRay.direction * camDistance, Color.magenta);
                    }
                }
                else
                {
                    if (collisionDebug)
                        Debug.DrawLine(camRay.origin, camRay.origin + camRay.direction * camDistance, Color.cyan);
                }

                currentRay++;
            }
        }

        if (isColliding)
        {
            float minRayDistance = float.MaxValue;
            currentRay = 0;

            for (int i = 0; i < rayColHit.Length; i++)
            {
                if (rayColHit[i])
                {
                    float colDistance = Vector3.Distance(rayColOrigin[i], rayColPoint[i]);

                    if (colDistance < minRayDistance)
                    {
                        minRayDistance = colDistance;
                        currentRay = i;
                    }
                }
            }

            Vector3 clipCenter = transform.position - (tilt.forward * currentDistance);

            adjustedDistance = Vector3.Dot(-mainCam.transform.forward, clipCenter - rayColPoint[currentRay]);
            adjustedDistance = currentDistance - (adjustedDistance + collisionCushion);
            adjustedDistance = Mathf.Clamp(adjustedDistance, 0, camMaxDistance);
        }
        else
            adjustedDistance = currentDistance;
    }

    void CameraXAdjust()
    {
        if (cameraState != CameraState.CameraRotate)
        {
            if (camXAdjust)
            {
                rotationXSpeed += Time.deltaTime * cameraAdjustSpeed;

                if (Mathf.Abs(panAngle) > rotationXCushion)
                    currentPan = Mathf.Lerp(currentPan, currentPan + panAngle, rotationXSpeed);
                else
                    camXAdjust = false;
            }
            else
            {
                if (rotationXSpeed > 0)
                    rotationXSpeed = 0;

                currentPan = player.transform.eulerAngles.y;
            }
        }
    }

    void CameraYAdjust()
    {
        if (cameraState == CameraState.CameraNone)
        {
            if (camYAdjust)
            {
                rotationYSpeed += (Time.deltaTime / 2) * cameraAdjustSpeed;

                if (currentTilt >= yRotMax || currentTilt <= yRotMin)
                    currentTilt = Mathf.Lerp(currentTilt, yRotMax / 2, rotationYSpeed);
                else if (currentTilt < yRotMax && currentTilt > yRotMin)
                    camYAdjust = false;
            }
            else
            {
                if (rotationYSpeed > 0)
                    rotationYSpeed = 0;
            }
        }
    }
    void CameraNeverAdjust()
    {
        switch (cameraState)
        {
            case CameraState.CameraSteer:

                if (panOffset != 0)
                    panOffset = 0;

                currentPan = player.transform.eulerAngles.y;
                break;

            case CameraState.CameraNone:
                currentPan = player.transform.eulerAngles.y - panOffset;
                break;

            case CameraState.CameraRotate:
                panOffset = panAngle;
                break;
        }
    }

    public enum CameraState
    {
        CameraNone,
        CameraRotate,
        CameraSteer

    }
    public enum CameraMoveState
    {
        OnlyWhileMoving,
        OnlyHorizontalWhileMoving,
        AlwaysAdjust,
        NeverAdjust

    }

    public void OnDisabled()
    {
        Cursor.visible = true;
        Cursor.lockState = CursorLockMode.None;
        enabled = false;

    }
 
}

As you can see the camera has a lot of features. I been working on it a very long time.

Note: I was going to use the Free character controller but I dont like all its dependencies. Just thought I’d make note of that. Thanks.