- Home /
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.
Answer by haruna9x · Feb 24 at 07:37 AM
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);
}
Thank you so much for this! I knew the solution was something along these lines but I hammered it out on paper for a couple hours and couldn't get the right conversion. This idea works perfectly.
Your answer
Follow this Question
Related Questions
Character Movement w/ Both Joysticks 0 Answers
2 virtual joysticks controlling 2 different game objects ( players ) pls help 0 Answers
3D Top down movement. Move towards the mouse position. 1 Answer
Unity2D Space shooter rotation resetting when analogue stick input has ended 1 Answer
Multiplayer Movement 0 Answers