- Home /
How can I play a specific animation upon a combination of inputs using the Blend Tree?
I am using a 2D Freeform Cartesian blend type to move my sprite around in a 2D top-down, Zelda-like game. My up, down, left, and right animations are working just fine. But I am having an issue with a specific animation playing upon a combination of inputs. When walking left, and only then up, for example (diagonal northwest), I want the left animation to continue playing instead of the up animation. When walking down, and then right, as another example, I want the down animation to continue playing (basically, the input that was pressed first should have the animation that is associated with it should play).
Is this possible using the blend tree? I am attempting to do this using a bunch of if statements and counters (if left is pressed, ++, if up is pressed, ++, and if count == 2, trigger that specific animation), which is not all that straight forward or simple, it seems. Is there an easier way using the blend tree?
Also, I am not using Input.GetButtonDown, etc. because I want this code to be usable by NPCs and other non-controllable characters. I am setting floats as parameters in the blend tree and triggering the animations in this way.
Answer by AssembledVS · Jul 09, 2015 at 06:52 AM
I figured it out. A forum user named DrHeinous got me started in the right direction:
The trick seems to be to using counters to see if the right combination and order of inputs is pressed:
// Update ################################################################################### //
void Update()
{
// movement ============================================================================= //
// get player input and store values as floats
// default settings from "Edit -> Project Settings -> Input"; already mapped to arrow keys;
// inputs will be 0, 1, or -1, which determine the direction of movement on a coord
// plane; no key press is 0, right is 1, left is -1, up is 1, down is -1
animInputLeftRight = Input.GetAxisRaw("Horizontal"); // 0.0f, 1.0f, or -1.0f
animInputUpDown = Input.GetAxisRaw("Vertical"); // 0.0f, 1.0f, or -1.0f
// set movement inputs to values of animation inputs; this is done in order to separate
// animations from movement, as some animations should play regardless of what the
// movement inputs are
moveInputLeftRight = animInputLeftRight;
moveInputUpDown = animInputUpDown;
// define movement as the direction for both axes multiplied by 'playerSpeed'
playerMovement = new Vector2(moveInputLeftRight * playerSpeed.x,
moveInputUpDown * playerSpeed.y);
// animation ============================================================================ //
// favoring an animation is only done for up/down animations, as left/right animations are
// already favored while moving left, then up/down, or right, then up/down; the
// horizontal animations favored by default because their motions are listed first in
// the blend tree, and the first motions seem to be always favored by Unity
// up, then left or right --------------------------------------------------------------- //
// when moving up, then left/right (northwest/northeast), favor up animation
if (animInputUpDown == 1)
{
upLeftRightCounter++;
}
else
{
upLeftRightCounter = 0;
upLeftRightMotion = false;
}
if (animInputLeftRight != 0)
{
upLeftRightCounter++;
}
else
{
upLeftRightCounter = 0;
upLeftRightMotion = false;
}
// if counter = 2, up, then left/right motion is triggered
if (upLeftRightCounter == 2)
{
upLeftRightMotion = true;
}
// if motion is triggered, set y animation value to up (1)
if (upLeftRightMotion == true)
{
animInputLeftRight = 0;
animInputUpDown = 1;
}
// down, then left or right ------------------------------------------------------------- //
// when moving down, then left/right (southwest/southeast), favor down animation
if (animInputUpDown == -1)
{
downLeftRightCounter++;
}
else
{
downLeftRightCounter = 0;
downLeftRightMotion = false;
}
if (animInputLeftRight != 0)
{
downLeftRightCounter++;
}
else
{
downLeftRightCounter = 0;
downLeftRightMotion = false;
}
// if counter = 2, up, then left/right motion is triggered
if (downLeftRightCounter == 2)
{
downLeftRightMotion = true;
}
// if motion is triggered, set y animation value to down (-1)
if (downLeftRightMotion == true)
{
animInputLeftRight = 0;
animInputUpDown = -1;
}
// trigger animations ------------------------------------------------------------------- //
// if no inputs are 0, there is movement; set variables to trigger appropriate animations
if ((moveInputLeftRight != 0) || (moveInputUpDown != 0))
{
playerAnimator.SetBool("isWalking", true);
playerAnimator.SetFloat("inputX", animInputLeftRight); // will be either 1 or -1
playerAnimator.SetFloat("inputY", animInputUpDown); // will be either 1 or -1
}
// else inputs are 0, so there is no movement, therefore character is not walking
else
{
playerAnimator.SetBool("isWalking", false);
}
}
// FixedUpdate ############################################################################## //
void FixedUpdate()
{
// set the player obj's rigidbody2D velocity to player movement (direction * speed = vel)
playerRigidBody.velocity = playerMovement;
}
Your answer
Follow this Question
Related Questions
3D, Top Down, Twin stick, Strafing animation problem 0 Answers
How to select an animation clip by index number? 7 Answers
2D: initial sprite idle animation playing too fast upon game initiation until I input movement keys? 1 Answer
Is it possible to combine animations from different character rigs ? 1 Answer
How to make realistic 2D balloon physics 0 Answers