2

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;
         }             
             
     }
 
 }
Pur3333
  • 21
  • 4

1 Answers1

1

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)

Mahdad Baghani
  • 779
  • 12
  • 25
  • Thanks for the reply. I did end up trying this as well as a bunch of things and while it does rotate the player correctly, the vectors still seem to be global so W is still forward relative to the game world and not where the camera is facing, I guess I need a way to transfer the vectors passed through via the input system into local vectors relative to the camera and player but I'm not sure how. – Pur3333 Dec 26 '20 at 19:32
  • 1
    I edited the original answer to remind you that you are still passing the `inputVector * speed` as the velocity of the rigidbody, which does not consider the player rotation. Try the newly edited answer. – Mahdad Baghani Dec 26 '20 at 20:19
  • I'll try this when I get home thank you :) – Pur3333 Dec 27 '20 at 01:53
  • Hi, this worked pretty well! I think any bugs are due to some other code related to the rigidbody. I had to replace the player x/z angles with 0 since otherwise he just started floating away. If I wanted to reverse the camera spin is there any easy way to reverse the angle? Or the spin? Thank you. – Pur3333 Dec 27 '20 at 23:30
  • Actually, sorry to be "that guy" but now the character ignores left and right inputs, only going where the camera looks when moving forward, which is what I want, but kinda wanted both at the same time. It might be hard to understand from my explanation but if you watch a video of Devil May Cry 5, it is essentially that movement im after. – Pur3333 Dec 27 '20 at 23:38
  • 1
    That is perfectly fine. I didn't quite understand all of the aspects of the question. The problem is that the movement was applied via rigid body.velocity in the direction of `player.forward`, and only checked the magnitude of the input vector so the player wouldn't move when you don't press the move axes. Check the newly updated answer. – Mahdad Baghani Dec 28 '20 at 06:20
  • glad I could be of any help. – Mahdad Baghani Dec 28 '20 at 15:00