How to determine 2D Directional animation based on player direction in a top down game

So this is difficult to explain but I’ll try. As you can see in the attached image, I am using a blend tree to determine the animations for the player in a top down game. So if the player is moving straight, MoveX should be 1 and MoveZ should be 0, and similarly for the other directions the character could move. All of this works when the player is facing to the top of the screen. However, when the player turns anywhere but the top of the screen, the animation isn’t in sync with the direction the player is actually moving.


For instance, if the player is turned to the right of the screen, its Y rotation is 90. I basically want to make it so the way the player is facing should determine where MoveX and MoveY start at (0,1) respectively. This way if the player is facing right (y = 90), and moving to the right side of the screen, MoveX and MoveY should be (0,1) so the animation shows the player going forward. Then, if player faces right but moves to the left of the screen, the animation should be running backwards which would be MoveX = 0 and MoveZ = -1. Right now this would be MoveX = -1 and MoveZ = 0 so the animation is running left.

Here is my function for movement thats called every frame. It uses an on-screen joystick or gamepad left stick to move the player. Im looking for what i should set anim.SetFloat(“MoveX”, …); to for the correct animation to play (and likewise for MoveZ).

    void MovementUpdate()
    {
        Vector2 movementInput = playerInput.PlayerControls.Movement.ReadValue<Vector2>();
        Vector3 move = new Vector3(movementInput.x, 0f, movementInput.y);
        controller.Move(move * Time.deltaTime * playerSpeed);

        float joystickAmount = Mathf.Max(Mathf.Abs(movementInput.x), Mathf.Abs(movementInput.y));
        anim.SetFloat("MoveX", movementInput.x);
        anim.SetFloat("MoveZ", movementInput.y);
        //Debug.Log(movementInput);
        Debug.Log(gameObject.transform.rotation.y);

        if (move != Vector3.zero)
        {
            gameObject.transform.forward = move;
        }
    }

I also don’t know much about blend trees so if there’s a different blend type I could do that would easily implement player direction in with the X and Z of the joystick, that would be great.

You need to convert the movementInput vector in the direction of the character’s face (take Vector2.up as the default direction). Use the converted vector to send to the Animator.

private Vector2 ConvertMovementInput(Transform playerTrans, Vector2 movementInput) {
        Vector2 playerDir = new Vector2(playerTrans.forward.x, playerTrans.forward.z);
        float angleDiff = Vector2.SignedAngle(Vector2.up, playerDir);
        return Rotate(movementInput, -angleDiff);
    }

    private Vector2 Rotate(Vector2 v, float degrees) {
        float radians = degrees * Mathf.Deg2Rad;
        float sin = Mathf.Sin(radians);
        float cos = Mathf.Cos(radians);

        float tx = v.x;
        float ty = v.y;

        return new Vector2(cos * tx - sin * ty, sin * tx + cos * ty);
    }