Animation relative to facing direction

Hi, I’m using a 2D freeform directional blend tree for my animation and it works fine but the problem is that the animation does not play relative to the players rotation. So i somehow need to take the rotation into count when playing the animation.

Quick example: if the player has rotated 90 degrees and press W the character will move up as it should but it does so doing the walk animation forward which looks weird it should know the player is facing a different direction and instead play the sidewalk animation.

I made a very simple sketch to show my problem more clearly
(img wont work so heres the link)

Here’s my code for moving, turning the player and animation.

    void FixedUpdate()
    {
        // Store the input axes.
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        // Move the player around the scene.
        Move(h, v);

        // Turn the player to face the mouse cursor.
        Turning();

        // Animate the player.
        Animating(h, v);
    }

    void Move(float h, float v)
    {
        // Set the movement vector based on the axis input.
        movement.Set(h, 0f, v);

        // Normalise the movement vector and make it proportional to the speed per second.
        movement = movement.normalized * speed * Time.deltaTime;

        // Move the player to it's current position plus the movement.
        playerRigidbody.MovePosition(transform.position + movement);
    }

    void Turning()
    {
        // Create a ray from the mouse cursor on screen in the direction of the camera.
        Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);

        // Create a RaycastHit variable to store information about what was hit by the ray.
        RaycastHit floorHit;

        // Perform the raycast and if it hits something on the floor layer...
        if (Physics.Raycast(camRay, out floorHit, camRayLength, floorMask))
        {
            // Create a vector from the player to the point on the floor the raycast from the mouse hit.
            Vector3 playerToMouse = floorHit.point - transform.position;

            // Ensure the vector is entirely along the floor plane.
            playerToMouse.y = 0f;

            // Create a quaternion (rotation) based on looking down the vector from the player to the mouse.
            Quaternion newRotation = Quaternion.LookRotation(playerToMouse);

            // Set the player's rotation to this new rotation.
            playerRigidbody.MoveRotation(newRotation);
        }
    }

    void Animating(float h, float v)
    {
        anim.SetFloat("Horizontal", h, 0.05f, Time.deltaTime);
        anim.SetFloat("Vertical", v, 0.05f, Time.deltaTime);
    }
}
1 Like

As usual unity forums is no help, if anyone else stumbles into this problem here is how I solved it

    private Vector3 moveDirection = Vector3.zero;


   void Animating(float h, float v)
    {
        moveDirection = new Vector3(h, 0, v);

        if (moveDirection.magnitude > 1.0f)
        {
            moveDirection = moveDirection.normalized;
        }

        moveDirection = transform.InverseTransformDirection(moveDirection);

        anim.SetFloat("Horizontal", moveDirection.x, 0.05f, Time.deltaTime);
        anim.SetFloat("Vertical", moveDirection.z, 0.05f, Time.deltaTime);
    }
}

Source: Cant get Twin Stick Movement/Aiming animations right

13 Likes

Yep, you did help more than the Unity forums, Thank you!

1 Like

Thanks, that IntervseTransformDirection helped me in the same situation.

1 Like

It’s 2020. I spent all night pulling my hair out and ultimately gave up and went to bed, my mind racing with trying to figure out just how the eff to solve this, not even sure of the question I am trying to ask. The next morning I somehow find my way to this post. You have been extremely helpful! Thank you!

4 Likes

Thanks for that! Helped me as well. In case anyone is wondering, line 13 is where the magic is.

" moveDirection = transform.InverseTransformDirection(moveDirection);"

1 Like

For me " moveDirection = transform.InverseTransformDirection(moveDirection);" sets my x, y blend tree parameters to the same value and doesnt go into negatives. Forcing the blend tree to be stuck on the same animation. Is this meant to happen?

Worked like a charm. Thanks!

1 Like

2023 here, not even ChatGPT could figure this one out. This worked great. Thanks!

2 Likes

I think one thing that can be easy to forget about is the difference between world space and local space. Its a good thing to always keep in mind which space your operating in.

1 Like

You’re a god. Even years later. I searched everywhere trying to find a solution to this. And everything was like these huge intricate tutorials that wouldn’t work. This was just one line of code I was missing. moveDirection = transform.InverseTransformDirection(moveDirection);
Ahhh I feel complete ive been scratching my head at this for hours.

1 Like

Hello from 2024, worked like a charm, thank you for this!

1 Like