- Home /
Other. Restarted the code from the ground up. It now works as intended.
How to get a character to turn in the direction of the camera?
I've hit a roadblock where when I move the camera, while moving, the character rotates on the spot however, their direction in where they are heading changes when I update the left thumbstick.
This is odd as updating it in Update doesn't work and forces the character to move in circles and placing it in a bit of script that updates with the right thumbstick is moved, causes the character to rotate and move in very different directions that what I want it to go in. This is temporarily fixed when I move the left thumbstick, updating the character's movement.
The controls for this are: Left Thumbstick - Move player, Right Thumbstick - Move camera, East Button - Jump, North Button - Run.
The goal is to allow the character to rotate themselves as well as their direction when I move the camera rather than them only updating their direction when I move the left thumbstick.
Before the code, these are the packages I'm currently using within Unity that effect this: Cinemachine & Input System.
Here's the movement code that this is effecting:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
private DefaultControls controls;
[Header("Unity General")]
[SerializeField]
private CharacterController controller;
public Transform cameraTransform;
public InputActionReference cameraControl;
[Header("General Settings")]//Player movement.
public bool canMovePlayer;
private Vector2 currentMovementInput;
private Vector3 currentMovement;
private Vector3 currentRunMovement;
private bool isMovementPressed;
private bool isRunPressed;
[Space]//Animator stuff.
public Animator characterAnimator;
private int isWalkingHash;
private int isRunningHash;
[Space]//Player running speed & how fast the player will turn when going left or right.
public float rotationFactorPerFrame = 15.0f;
public float runMultiplier = 3.0f;
[Space]//Default gravity for when the player is falling and gravity for when the player is grounded.
public float gravity = -9.81f;
public float groundedGravity = -0.05f;
[Space]//Playing jumping.
public float initialJumpVelocity;
private bool isJumpPressed = false;
private float maxJumpHeight = 1f;
private float maxJumpTime = 0.5f;
private bool isJumping = false;
private int isJumpingHash;
private bool isJumpAnimating = false;
private void Start()
{
Cursor.lockState = CursorLockMode.Locked;
npcInteraction = GetComponent<NPCInteraction>();
}
private void Awake()
{
controls = new DefaultControls();
controller = GetComponent<CharacterController>();
isWalkingHash = Animator.StringToHash("isWalking");
isRunningHash = Animator.StringToHash("isRunning");
isJumpingHash = Animator.StringToHash("isJumping");
controls.Movement.Walking.started += OnMovementInput;
controls.Movement.Walking.canceled += OnMovementInput;
controls.Movement.Walking.performed += OnMovementInput;
controls.Movement.Run.started += OnRun;
controls.Movement.Run.canceled += OnRun;
controls.Movement.Jump.started += OnJump;
controls.Movement.Jump.canceled += OnJump;
SetupJumpVariables();
}
private void SetupJumpVariables()
{
float timeToApex = maxJumpTime / 2;
gravity = (-2 * maxJumpHeight) / Mathf.Pow(timeToApex, 2);
initialJumpVelocity = (2 * maxJumpHeight) / timeToApex;
}
private void HandleJump()
{
if (!isJumping && controller.isGrounded && isJumpPressed)
{
characterAnimator.SetBool(isJumpingHash, true);
isJumpAnimating = true;
isJumping = true;
currentMovement.y = initialJumpVelocity * 0.5f;
currentRunMovement.y = (initialJumpVelocity + 0.5f) * 0.5f;
}
else if (!isJumpPressed && isJumping && controller.isGrounded)
{
isJumping = false;
}
}
private void OnJump(InputAction.CallbackContext context)
{
isJumpPressed = context.ReadValueAsButton();
}
private void OnRun(InputAction.CallbackContext context)
{
isRunPressed = context.ReadValueAsButton();
}
private void HandleRotation()
{
Vector3 positionToLookAt;
//Change in position our character should point to.
positionToLookAt.x = currentMovement.x;
positionToLookAt.y = 0.0f;
positionToLookAt.z = currentMovement.z;
//Current rotation of our character.
Quaternion currentRotation = transform.rotation;
if (currentMovementInput != Vector2.zero)
{
//Creates a new rotation based on where the player is currently pressing.
float targetAngle = Mathf.Atan2(currentMovementInput.x, currentMovementInput.y) * Mathf.Rad2Deg + cameraTransform.eulerAngles.y;
Quaternion targetRotation = Quaternion.Euler(0f, targetAngle, 0f);
transform.rotation = Quaternion.Lerp(currentRotation, targetRotation, rotationFactorPerFrame * Time.deltaTime);
}
}
private void OnMovementInput(InputAction.CallbackContext context)
{
currentMovementInput = context.ReadValue<Vector2>();
currentMovement = new Vector3(currentMovementInput.x, 0f, currentMovementInput.y);
currentRunMovement.x = currentMovementInput.x * runMultiplier;
currentRunMovement.z = currentMovementInput.y * runMultiplier;
MovementDirection();
isMovementPressed = currentMovementInput.x != 0 || currentMovementInput.y != 0;
}
private void MovementDirection()
{
currentMovement = cameraTransform.forward * currentMovement.z + cameraTransform.right * currentMovement.x;
currentMovement.y = 0f;
currentRunMovement = cameraTransform.forward * currentRunMovement.z + cameraTransform.right * currentRunMovement.x;
currentRunMovement.y = 0f;
}
private void HandleAnimation()
{
bool isWalking = characterAnimator.GetBool(isWalkingHash);
bool isRunning = characterAnimator.GetBool(isRunningHash);
if (isMovementPressed && !isWalking)
{
characterAnimator.SetBool(isWalkingHash, true);
}
else if (!isMovementPressed && isWalking)
{
characterAnimator.SetBool(isWalkingHash, false);
}
if ((isMovementPressed && isRunPressed) && !isRunning)
{
characterAnimator.SetBool(isRunningHash, true);
}
else if ((!isMovementPressed || !isRunPressed) && isRunning)
{
characterAnimator.SetBool(isRunningHash, false);
}
}
private void HandleGravity()
{
bool isFalling = currentMovement.y <= 0.0f;
float fallMultiplier = 1.5f;
if (controller.isGrounded)
{
characterAnimator.SetBool(isJumpingHash, false);
isJumpAnimating = false;
currentMovement.y = groundedGravity;
currentRunMovement.y = groundedGravity;
}
else if (isFalling)
{
float previousYVelocity = currentMovement.y;
float newYVelocity = currentMovement.y + (gravity * fallMultiplier * Time.deltaTime);
float nextYVelocity = (previousYVelocity + newYVelocity) * 0.5f;
currentMovement.y = nextYVelocity;
currentRunMovement.y = nextYVelocity;
}
else
{
float previousYVelocity = currentMovement.y;
float newYVelocity = currentMovement.y + (gravity * Time.deltaTime);
float nextYVelocity = (previousYVelocity + newYVelocity) * 0.5f;
currentMovement.y = nextYVelocity;
currentRunMovement.y = nextYVelocity;
}
}
// Update is called once per frame
public void Update()
{
HandleRotation();
HandleAnimation();
controller.Move(currentMovement * Time.deltaTime);
characterAnimator.SetFloat("Speed", controls.Movement.Walking.ReadValue<Vector2>().magnitude);
if (isRunPressed)
{
controller.Move(currentRunMovement * Time.deltaTime);
}
else
{
controller.Move(currentMovement * Time.deltaTime);
}
HandleGravity();
HandleJump();
if (cameraControl.action.triggered)
{
MovementDirection();
}
LockOnTarget();
Interaction();
}
private void OnEnable()
{
controls.Movement.Enable();
}
private void OnDisable()
{
controls.Movement.Disable();
}
}
Follow this Question
Related Questions
ps3 controller messed up the normal controls 1 Answer
drag to move object in perspective camera 0 Answers
I need to make the Camera Quit snapping to center... 1 Answer
Simple Object Dragging 0 Answers