Character/Camera rotation

Hello everyone :slight_smile:.

I am working on a Third Person controller with the use of Cinemachine, the issue I am having is using the camera’s orientation to handle rotation. The reason I am doing it this is way is for example the player pressed s and is now facing backwards and if the player turns to the character’s back and presses W and goes forward (facing the same direction it was when pressing S). Simple movement, but the issue with that IS THE ORIENTATION.

When I move on Vector3.right it works like a beauty, but when handling with forward orientation is makes my character want to fly up in the sky ?.. without my cameras.forward it would leave the character in a janky position and thats not what i want.

can anybody give me some pointers on my script and tell me what is wrong? thank you very much :slight_smile:

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

public class PL_Controller : MonoBehaviour
{
    // Components
    Rigidbody rb;
    Animator animator;

    // Player Variables
    public Transform cameraTransform;
    public Vector3 playerInput;
    public float moveSpeed = 5f;
    public float rotationSpeed = 2f;
    public float playerX, playerZ;

    // Start is called before the first frame update
    void Start()
    {
        // Components
        rb = GetComponent<Rigidbody>();
        animator = GetComponent<Animator>();

        // Lock cursor & Hide it
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;


    }

    // Update is called once per frame
    void Update()
    {
        // Grab Horizontal and Vertical Input
        playerX = Input.GetAxisRaw("Horizontal");
        playerZ = Input.GetAxisRaw("Vertical");

        // Store player input in playerInput
        playerInput = (Vector3.right * playerX + Vector3.forward * playerZ).normalized;
    }

    // Using FixedUpdate for Physics
    private void FixedUpdate()
    {
        MoveDirection(playerInput);
        HandleRotation();
    }

    /* Massive bug I need to fix is fixing the players rotation. For example when the character presses S it goes backwards which works as intended.
     * However, when you turn to the character's back and press W it turns around and goes the other direction. This is because it is tied to global input,
     * rather than adapting to the camera's orientation. The solution to this is to rotate the character based on the camera's forward direction.
     * 
     */
    void MoveDirection(Vector3 direction)
    {
        // Get camera forward and right direction
        Vector3 cameraForward = cameraTransform.forward;
        Vector3 cameraRight = cameraTransform.right;

        // Make sure in the vectors the y is flat (ignore Y-axis)
        cameraForward.y = 0;
        cameraRight.y = 0;

        // Normalize to avoid any unwanted issues
        cameraForward.Normalize();
        cameraRight.Normalize();

        // Move in the direction relative to the camera
        Vector3 moveDirection = direction.x * cameraRight + direction.z * cameraForward; 
        
        // Apply movement to rigidbody
        rb.velocity = moveDirection * Time.fixedDeltaTime * moveSpeed;

        // Update Animator float values
        animator.SetFloat("X", playerX);
        animator.SetFloat("Y", playerZ);

    }

    void HandleRotation()
    {
        // Only handle rotation when there is any player input
        if (playerInput.magnitude > 0.1f)
        {
            // Get camera forward
/*            Vector3 cameraForward = cameraTransform.forward;
            cameraForward.y = 0;
            cameraForward.Normalize();*/

            // Created targetDirection representing player input
            Vector3 targetDirection = (Vector3.right * playerX + Vector3.forward * playerZ).normalized;

            // Combine targetDirection with camera's forward direction
            Vector3 moveDirection = targetDirection.x * cameraTransform.right + targetDirection.z * cameraTransform.forward;

            // Creates rotation based on input
            Quaternion targetRotation = Quaternion.LookRotation(moveDirection);

            // Smoothly rotate current rotation to targetRotation
            Quaternion playerRotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);

            // Set current rotation to playerRotation
            transform.localRotation = playerRotation;
        }
    }
}

i got it everybody :)… if anyone has the same issue the solution was in the rotation method. the Y axis isnt being handled at all which is why its making the character turn based on the cameras y position. so to correct this it would look like this

    void HandleRotation()
    {
        // Only handle rotation when there is any player input
        if (playerInput.magnitude > 0.1f)
        {
            // Get camera forward
/*            Vector3 cameraForward = cameraTransform.forward;
            cameraForward.y = 0;
            cameraForward.Normalize();*/

            // Created targetDirection representing player input
            Vector3 targetDirection = (Vector3.right * playerX + Vector3.forward * playerZ).normalized;

            // Combine targetDirection with camera's forward direction
            Vector3 moveDirection = targetDirection.x * cameraTransform.right + targetDirection.z * cameraTransform.forward;
            moveDirection.Normalize();
            moveDirection.y = 0;

            // Creates rotation based on input
            Quaternion targetRotation = Quaternion.LookRotation(moveDirection);

            // Smoothly rotate current rotation to targetRotation
            Quaternion playerRotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);

            // Set current rotation to playerRotation
            transform.localRotation = playerRotation;
        }
    }

moveDirection has to be normalized and the y has to be kept flat 0