so far I have a working movement system using Rigidbody and the new Input System. I have it set up so that WASD passes through the input which then moves the character forward, back, left and right while also facing that direction when pressed.
I also have a FreeLook Cinemachine camera that follows the player as they move which works well enough for now and can be moved around the player.
Additionally I want to add functionality so that "forward" and by extension the other movement options are in context with the direction the camera is facing. So if you move the camera around in front of the player then "forward" would now be the opposite direction and so on. This is the part I am stuck on as i'm not sure how to change my inputs from forward, to be forward with respect to the camera. Should I just rotate the entire GameObject in relation to the camera? But I only want the character to rotate if they are trying to move.
tl;dr DMC5 movement system, if its easier to show and not tell. Heres what I have so far:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerCharacterController : MonoBehaviour
{
private PlayerActionControls _playerActionControls;
[SerializeField]
private bool canMove;
[SerializeField]
private float _speed;
private Vector2 _playerDirection;
private GameObject _player;
private Rigidbody _rb;
private Animator _animator;
private void Awake()
{
_playerActionControls = new PlayerActionControls();
_player = this.gameObject;
_rb = _player.GetComponent<Rigidbody>();
}
private void OnEnable()
{
_playerActionControls.Enable();
_playerActionControls.Default.Move.performed += ctx => OnMoveButton(ctx.ReadValue<Vector2>());
}
private void OnDisable()
{
_playerActionControls.Default.Move.performed -= ctx => OnMoveButton(ctx.ReadValue<Vector2>());
_playerActionControls.Disable();
}
private void FixedUpdate()
{
Vector3 inputVector = new Vector3(_playerDirection.x, 0, _playerDirection.y);
transform.LookAt(transform.position + new Vector3(inputVector.x, 0, inputVector.z));
_rb.velocity = inputVector * _speed;
}
private void OnMoveButton(Vector2 direction)
{
if (canMove)
{
_playerDirection = direction;
}
}
}
According to this post on Unity Forum, you can use player.transfrom.eulerAngles
instead of LookAt
function.
This is possibly how you can rewrite your FixedUpdate
, assuming that you want to rotate your character around Y axis using the angle of the camera:
Vector3 inputVector = new Vector3(_playerDirection.x, 0, _playerDirection.y);
// rotate the player to the direction the camera's forward
player.transform.eulerAngles = new Vector3(player.transform.eulerAngles.x,
cam.transform.eulerAngles.y, player.transform.eulerAngles.z);
// "translate" the input vector to player coordinates
inputVector = player.transform.TransformDirection(inputVector);
_rb.velocity = inputVector * _speed;
(of course the references to player
and cam
are intended as pseudo-code, replace them with appropriate references)