Problems with rotation on a player controller

Hello! This is my first time posting. I’m taking the Apply object oriented principles Mission on the Junior programmer Pathway and I’m learning a lot. I’ve also watched a few tutorials and I have been doing some research on my own. I have seen some character controller tutorials and I was curious to give it a shot at one. It worked! Now I even can add animations on the animator and they work. But there is a problem; when the character runs into a wall or an object with a collider, it rotates as if trying to find a way around the obstacle. I’m using the Character Controller component and I have this in my script

csharp
    public static PlayerController Instance { get; private set; }
    [Header("References")]
    private CharacterController controller;
    [SerializeField] private Camera mainCamera;

    [Header("Movement Settings")]
    [SerializeField] private float moveSpeed = 5.0f;
    [SerializeField] private float turnSpeed = 2.0f;

    [Header("Input")]
    private float moveInput;
    private float turnInput;

    private void Awake()
    {
        if (Instance != null)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        DontDestroyOnLoad(gameObject);
        Initialize();
        currentHealth = maxHealth;
    }

    private void Initialize()
    {
        if (mainCamera == null)
        {
            mainCamera = Camera.main;
        }
        controller = GetComponent<CharacterController>();
    }

    private void Update()
    {
        InputManager();
        MovementManager();
    }

    private void InputManager()
    {
        moveInput = Input.GetAxisRaw("Vertical");
        turnInput = Input.GetAxisRaw("Horizontal");
    }
    private void MovementManager()
    {
            Movement();
            if (mainCamera == null)
            {
                mainCamera = Camera.main;
            }
            if (mainCamera != null)
            {
                RotateCamera();
            }
    }


    private void Movement()
    {
        grounded = controller.isGrounded;
        Vector3 move = new Vector3(turnInput, 0, moveInput);
        move = mainCamera.transform.TransformDirection(move).normalized;

        move.z *= moveSpeed;
        move.x *= moveSpeed;
        move.y = 0;
        controller.Move(move * Time.deltaTime);
    }

    private void RotateCamera()
    {
        if (Mathf.Abs(turnInput) > 0 || Mathf.Abs(moveInput) > 0)
        {
            Vector3 currentLookDirection = controller.velocity.normalized;
            currentLookDirection.y = 0;

            currentLookDirection.Normalize();

            if (currentLookDirection != Vector3.zero)
            {
                Quaternion targetRotation = Quaternion.LookRotation(currentLookDirection);
                transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * turnSpeed);
            }

        }
    }

This is the code relevant to moving and rotating the player and camera, I’m using a Cinemachine camera with freelook as I started my controller before Unity 6 was released. I hope my code is readable and not too much spaghetti :disappointed_relieved:

Okay, the issue with the camera is not one with the code, it is the camera recognising the “Wall” or “Object” as physical and are colliding with them. There are couple ways to fix this, one is make the camera switch its position (ie make it go first person until you pull away from the wall) or tell it a list of objects it should not collide with

Oh, no! the camera works fine :sweat_smile:, and I know about the camera collider. You see, what rotates as if trying to find a way around the obstacle is the player character, so I’m not sure what is exaclty wrong

i think the problem could be in RotateCamera function. because i only see the transform.rotate there and you are rotating it based on velocity, so is it coming 0 after colliding with a wall?

1 Like

… because i only see the transform.rotate there and you are rotating it based on velocity, so is it coming 0 after colliding with a wall?

Yes, that’s what’s happening.
So instead of equaling the currentLookDirection to CharacterController.velocity i should equal it to it’s transform or just leave it as is?
I’m going to experiment on this, and later I’ll post if I have any findings. Thanks for pointing that out.

EDIT: I took out Vector3 move from the Movement() method and set it as a variable. Then I equaled currentLookDirection to it and now it works! Again, thank you very much for pointing that out! now it works as intended

1 Like