Hello everyone .
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
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;
}
}
}