Hi, I’m Nicky!
Welcome to my Channel about Game Development.
This is a video in a series dedicated to learning
Unity’s animation system.
In the previous video, we learned how to give
player’s control of multiple animations
using boolean parameters in combination with
our own code.
Today we are going to take our first look
at float parameters and we’ll learn how
to use them to dynamically blend animations
together with one dimensional blend trees.
Alright!
Let’s get going!
We left off our last video with a script that
controlled two boolean value parameters that
we added to our animator controller.
These two booleans controlled the transitions
between our idle, walk and run animation states.
To download animations, you can refer to episode
0 of this series.
All three animations are in-place animations,
so root motion will not be covered in this
tutorial.
For today’s example, let’s start by disconnecting
our walk and run animation states and just
move them to the side.
If you are coming from a blank project, let’s
add the idle animation as the default state.
Next, well hover over the grid, right click,
select “Create State” and “From New
Blend Tree”.
Immediately, we are presented with a new animation
state node titled “Blend Tree”.
Ok!
Great!
Now what makes it special?
What does a blend tree do?
A blend tree is used to dynamically “blend”
multiple animations together.
In our example today, we’ll see how we can
use our newly created blend tree to combine
our walk animation with our run animation,
resulting in dynamic animations that scale
between the two.
Last episode, we learned to use the “true”
or “false” boolean parameters.
But today is about floats because the actual
“blending” of our animations is dependent
on either one or two float parameters.
For now, we’ll start by creating a new float
parameter.
In the Parameter’s tab of the Animator window,
let’s press on the plus sign and select
Float.
Let’s rename this new parameter to “Speed”,
as this traditionally will reflect the speed
our character is moving in 3D space.
Let’s add transitions to our blend tree
also using the float parameter.
We’ll say if “velocity is greater than
0” for the transition to our blend tree,
and we’ll say “if the velocity is less
than “.05” for the transition back to
the idle state.
We use “.05” because it is a small enough
number that the only way that we have that
value for the velocity is if the player is
actually stopping or stopped.
Next, we’ll double click on our BlendTree
node.
This will navigate us into the blend tree’s
state layer in our grid window.
There’s not much to see at the start.
Just a single node with an adjustable parameter.
You’ll notice that it defaults to the velocity
parameter we just created.
If we were to add another float parameter,
we could change this setting by selecting
the parent node, and choosing the new parameter.
As said before, we’ll be blending our walk
and run animations together.
Below where we can select the Parameters,
we’ll see an Empty List titled Motion.
Pressing on this plus button, we’re presented
with two options: add Motion Field and New
Blend Tree.
Yes, you can have blend trees within blend
trees, and you can have blend trees within
those blend trees and so on.
For this example, we’ll use Motion Field,
then start by selecting our walking animation.
You’ll immediately notice a new node connected
to our parent node in our grid view, The node
will share the same title of its animation.
By selecting this node, we’ll see in the
inspector three animation options: loop Time,
loop Pose, and cycle offset.
Loop Time should already be selected from
this animation’s use in previous episodes.
But if it’s not, make sure that it is so
the animation will loop.
Loop Pose is used to blend an animation’s
starting and ending keyframes for animations
if they don’t already do so.
For example, let’s take a quick look at
our cube.
We’ll notice that when loop pose is deactivated,
the cube interpolates between the starting
point and the proceeding three points before
resetting the animation.
But when we toggle on loop pose, our animation
shifts and what was once 4 keys of animation
becomes three.
And if you haven’t seen the other episodes,
cycle offset adjusts the starting point of
the animation.
Currently, this blend tree works just like
our other animation states.
For example, if we press play and drag our
velocity value to the right, our character
will transition from the idle state to this
blend tree state and our walking animation
will play.
Now let’s say that our character had an
initial velocity that matched (or looked good
with) the speed of our walking animation.
But we want our character to start increasing
velocity the longer that the player holds
down “w” or pushes forward on an analog
stick.
The walking animation might be too slow, and
the running animation might be meant for our
characters maximum velocity.
What about the speeds in between?
Here lies the beauty of blend tree dynamic
animations.
The blend tree will generate animations more
fitting for the speed the character is moving
given that we pass in the speed as a parameter.
Let’s add our run animation by, again, pressing
on the plus button and "add motion field”.
A new graph will appear above our two animations
and now we’ll get to see this blend tree
in action.
Entering play mode, we’ll see that by dragging
the velocity value, our character will start
at our walk animation and end at our running
animation.
And In between will be dynamically created
animations.
Awesome!
Now that we’ve seen how we can blend the
two animations.
Let’s dive into our code!
We are going to start with a similar setup
to last episode.
We’ll set the reference for the animator
attached to our YBot and we’ll define and
properly format booleans for when the player
presses “w” and “left shift” to trigger
walk and run.
Next, we’ll set a new variable for velocity.
As stated before, we would normally correlate
this velocity value with the speed at which
the player is moving.
But in our example, we’re going to keep
the character stationary, so our velocity
variable will only be used to control the
animation.
Let’s put the velocity in control of the
player.
We’ll state if the player presses forward,
then we’ll increase the velocity by Time.deltaTime
multiplied by a variable we’ll call acceleration.
Time.deltaTime is the amount of time between
when the last frame was drawn.
Or this could be explained as “since the
Update function was last called” because
Update is called once per frame.
What this will do is allow our velocity to
increase at a steady rate!
We’ll define acceleration as a public float
variable so that we can modify the value through
our editor if we aren’t happy with the initial
increment we give it.
And lastly, we need to use the animator SetFloat
function to set our animator’s Velocity
parameter to the locally defined velocity
variable.
Let’s give this a try!
We’ll see that by pressing “w”, our
velocity parameter will start to increase!
And we’ll see that our character will slowly
start to velocity up!
However!
Letting go of “w”, our velocity parameter
stays the same!
But this is easily fixed!
Jumping back into our code, we’ll create
a new public float variable, this time called
“deceleration”!
Duplicating and modifying our conditional
statement, we will say “if the player is
not pressing forward”, then we want to decrease
the velocity by Time.deltaTime multiplied
by our deceleration variable.
However, this logic has one obvious flaw:
there is no limit to how low our velocity
value can go.
This is easily fixed by adding an additional
condition: we just need to add the condition
“if velocity is greater than 0”.
We will also add the condition if velocity
is less than 1 because with our current implementation
we don’t need to cover a velocity higher
than 1.
And we’ll add one more condition to reset
back to 0 in case the velocity drops below
0.
Awesome!
Let’s give this a shot.
We’ll now see that when we press w, our
velocity parameter will increase and when
we let go, it will decrease!
Perfect!
Now let’s go back and check out the settings
available in our blend tree.
Looking at our two motions, we’ll see three
options after their titles.
Threshold, a speed icon, and an icon of what
appears to be a body.
We’ll notice that threshold is greyed out.
This is because “Automate Thresholds”
is active.
By deactivating “automate thresholds”
we can now modify the thresholds for both
motions.
But what do they do?
Thresholds are used to distribute each motion
across the value of the blend tree’s parameter,
so in our case velocity.
Automate thresholds will try to evenly distribute
this.
As an example, we’ll set our bottom motion’s
threshold to five and modify our script so
we can reach a velocity of five.
In play mode, you’ll notice that as we press
“w”, it takes a lot longer to reach the
running animation.
And if we move the threshold of our walk animation
to four, it’s like we’re saying “ok,
up until the velocity reaches a value of four,
we want 100% of our blend tree to use the
walking animation”.
You’ll notice that “compute thresholds”
popped up when we deactivated “automate
thresholds”.
These options are for animations with root
motion.
While our own animations in this example do
not have root motion, this setting can be
understood as “Unity determining thresholds
based on an animation’s speed, velocity
x, y, or z, or angular speed in radians or
degrees.”
Next we have the animation’s speed setting.
Put simply, modifying this will increase or
decrease the playback speed of that particular
animation.
And this setting ties into our “adjust time
scale” dropdown which has just two options:
“reset time scale” and “homogeneous
speed”.
Reset time scale will reset all of the animations
speed values back to 1, and homogenous speed
is intended to rescale an animation’s speed
to fit within the minimum and maximum values
set in the motion list.
And last but not least we have the icon that
looks like the outline of a body.
This is the mirror option which will reflect
the animation.
This option is tied to humanoid characters.
When we get to our video covering animation
retargeting, we’ll learn more about humanoid
rigs!
Now this is a very simple setup.
In fact -- this is known as a one dimensional
Blend Tree, as can be seen by the Blend Type
in the inspector window.
Pressing on the blend type dropdown, we’ll
see 4 new options: 2D Simple Directional,
2D Freeform Directional, 2D Freeform Cartesian,
and Direct.
These are known as two dimensional blend trees
because instead of relying on a single parameter,
they rely on two!
In the next video we’ll explore these 2
dimensional blend trees using two float parameters.
And as the series continues, we’ll learn
to retarget these animations to our own characters!
As always, if you learned something new today,
please consider pressing that like button
and subscribing to the channel.
It really helps me and let’s me know we’re
headed in the right direction.
That’s all for today, thank you for watching,
and I’ll see you in the next video!
