unity-game-enginecoordinate-transformationinverse-transform

Unintended player movement from transform.InverseTransformDirection


this is my first time posting on here. I'm working on a game using the new Unity multiplayer networking solution. In summary, the issue is that the player is not moving as intended.

I am trying to take player input as follows:

Vector3 worldSpaceDir = new Vector3(Input.GetAxisRaw("Vertical"), 0, Input.GetAxisRaw("Horizontal"));

then convert it to the object space coordinates of the player character:

_inputDirection = transform.InverseTransformDirection(worldSpaceDir);

The issue I'm having is with a rotation of 0 or 180 the player moves as expected with the WASD inputs, however, at 90 or 270 all the inputs are flipped(A = right, D = left, W = backward, S = forward).

I found a question that is exactly my question but no one responded with an answer. The question is quite old now so I wanted to ask it again for more visibility.

Here's a link to the original question.


Solution

  • Firstly, you are taking the worldSpaceDir wrong, it should be as follow

    Vector3 worldSpaceDir = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
    

    here we take horizontal input as X and vertical input as Z, because in Unity Forward is pointed as Z and not Y.

    Secondly, we do not need to use InverseTransformDirection() we just need TransformDirection() something like following

    Vector3 inputDirection = transform.TransformDirection(worldSpaceDir);
    

    here we are telling unity to convert the worldSpaceDir that is relative to transform (local direction) into a world space direction, so we might actually give a proper name to worldSpaceDir.

    The following would work for you.

    private void Update() {
        Move();
    }
    
    private void Move() {
        Vector3 directionToMove = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
        Vector3 inputDirection = transform.TransformDirection(directionToMove);
        transform.position += inputDirection * Time.deltaTime;
    }