What is the match behind transform.InverseTransformDirection(Vector3)?

I’m trying to do server side movement and need to calculate the animator values.
In Unity I have a Move function where move is the agent.desiredVelocity or transform.forward and the turn/forward values of the animator are set after calling the InverseTransformDirection:

public void Move(Vector3 move) {

        if (move.magnitude > 1f) {
            move.Normalize();
        }

        move = transform.InverseTransformDirection(move);

        //Animator Values
        m_TurnAmount = Mathf.Atan2(move.x, move.z);
        m_ForwardAmount = move.z;
    }

I can’t make heads or tales of how the calculation is done so I can put this logic server side.

I’m using three.js / math3d.js in a node.js server but neither have this funciton.

I’ve commented the code for you so you can see what it’s doing. Hopefully that might help a little:

public void Move(Vector3 move)
{
    // Make sure the movement vector 'move' is normalised (i.e. has a length of 1)
    if (move.magnitude > 1f)
    {
        // Movement is longer than 1, normalise it (e.g. a movement of 1,1,0 would become 0.7,0.7,0)
        move.Normalize();
    }
 
    // To move the object we need to turn it's movement into the local space of it's object
    // For example, if it's object was rotated 90 degrees we need to factor that
    // rotation in so it's moving in the correct direction. e.g. If the 'move' was 90 degrees and the
    // object was already facing 90 degrees then 'move' would become 0 degrees.
    //
    // To do that we take the inverse of the parent object rotation ('transform') and multiply the
    // movement by it. In three.js you could get the parent's rotation as a quaternion,
    // call inverse() on it then multiply 'move' by that quaternion.
    //
    // Something like 'move = move * parentRotationQuaternion.inverse()'
    move = transform.InverseTransformDirection(move);

    //Animator Values
  
    // Calling Atan2 on a 2d vector will return the angle of that vector. Although we have a 3d movement
    // it's just getting the angle from the x and z parts and treating it as a 2d vector.
    m_TurnAmount = Mathf.Atan2(move.x, move.z);
    m_ForwardAmount = move.z;
}

That helped more than a little. I was able to get identical values in Unity using

Quaternion.Inverse(transform.rotation) * move

Once implemented on the server I am one step closer to server side movement. Thank you.

2 Likes