Location: Samples/01 Basics/02 Basic Movement
Recommended After: Quick Play
Learning Outcomes: in this sample you will learn:
How to respond to player input.
How to swap between different animations.
Summary
This sample demonstrates how to play a movement animation while you hold a key and return to an idle animation when you release the key.
The main logic looks like this:
protected virtual void Update()
{
float forward = SampleInput.WASD.y;
if (forward > 0)
{
_Animancer.Play(_Move);
}
else
{
_Animancer.Play(_Idle);
}
}
- This sample snaps between the animations instantly. Smooth blending is introduced in the Transitions sample.
- Playing an animation that was already playing doesn't automatically restart it so you don't need to check if it was already playing and can simply keep telling it to play the one you want every frame.
Overview
The code structure looks similar to the Quick Play sample, but now it has two animations:
Input
To make the character respond to user input, we use an Update
method (a MonoBehaviour Message which Unity will call every frame).
protected virtual void Update()
{
We won't be implementing full WASD movement in this sample, just W
to move forwards. That can be done in two steps:
- Get the value of
SampleInput.WASD
, which is aVector2
as explained in the Movement section on the Sample Input page. - Take only its
y
value, which is afloat
representing forwards and backwards based on theW
andS
keys.
Those two steps only take a single line though:
float forward = SampleInput.WASD.y;
That value will be:
1
whenW
is held.-1
whenS
is held.0
when neither button is held (or if both are held at the same time).
Animations
With the input value, we can use a simple if/else
statement to decide which animation we want Animancer to play.
...// Update method continued from above.
if (forward > 0)
{
_Animancer.Play(_Move);
}
else
{
_Animancer.Play(_Idle);
}
}
When you tell Animancer to play an animation:
- All other animations will be stopped (except if they're on different Layers).
- If that animation was already playing, it will continue playing uninterrupted. The Basic Action sample explains how you can make it restart from the beginning if that's what you want.
The above code was written like that to keep it simple for beginners, but it could actually be compacted into a single line using a Ternary Conditional Operator like this:
_Animancer.Play(forward > 0 ? _Move : _Idle);
Root Motion
By default, an Animator
component will use Root Motion which allows animations to cumulatively move the character around the scene instead of moving them along a specifically animated path.
But if we let it do that here, the character will walk off into the distance and won't be able to get back because this sample doesn't include the ability to turn or move backwards.
We don't want that to happen so we just disable the Apply Root Motion
toggle in the character's Animator
component which will make the character run in place without moving forwards.
The Root Motion page goes into more detail about how this feature can be used.
Conclusion
Here's what the full script looks like:
using Animancer;
using UnityEngine;
public class BasicMovementAnimations : MonoBehaviour
{
[SerializeField] private AnimancerComponent _Animancer;
[SerializeField] private AnimationClip _Idle;
[SerializeField] private AnimationClip _Move;
protected virtual void Update()
{
float forward = SampleInput.WASD.y;
if (forward > 0)
{
_Animancer.Play(_Move);
}
else
{
_Animancer.Play(_Idle);
}
}
}
Note how it doesn't need an OnEnable
method because the first Update
will take care of playing the appropriate animation before the first frame is rendered.
And here's what it looks like in action:
What Next?
Sample | Topic |
---|---|
Basic Action | Playing an Action animation when the user clicks and returning to Idle when it finishes. |
Transitions | Smoothly blending instead of instantly snappping between animations. |