You can create very robust animation with Unity's Mecanim system. In this tutorial we're going to go through creating a functional scene with root motion and use several examples of advanced animation with Mecanim. This tutorial will assume you have some basic understanding of Unity and Mecanim. If you're brand new to animation in Unity, you may want to check out our Mecanim Basics or Mixamo and Unity Overview. The information here is designed to be an example of some advanced uses of Mecanim. Designing good gameplay and creating logical transitions varies drastically between games, so use these as examples and customize them to suit your game!
We've packaged up the animations, characters, scripts and scene from this tutorial into a demo .unitypackage that you can import to your project to check out, customize, and use as examples to create your own content.
Import your Character
When preparing your character for Unity it should be alone in the scene, modeled to scale, facing forward and (if humanoid) in a t-pose. Export the file as an .fbx and then import that .fbx into Unity. In the inspector, go to the "Rig" tab and change the rig type to Humanoid or Generic. If you're not sure which one to use check out our Mecanim Animation Basics article. Have the import "Define a New Avatar" to create a definition of your character to use with Mecanim.
In the demo my characters are imported in the Demo > Characters folder as "Alpha@Alpha" and "Beta@Beta".
Import your Animations
Animations from Mixamo should be downloaded as separate .fbx files in .fbx for Unity format and with the option "skeleton only" turned on. This will ensure you're only importing the animation data, not duplicates of your mesh. Import each .fbx file into Unity.
To configure animations select all of the imported animation .fbx files in the Project view. In the "Rig" tab of the Inspector change the rig type to the same type that you used for the character (humanoid animations for humanoid characters). Set the Avatar Definition to "Copy from Other Avatar" and select the avatar from your t-pose import (no need to have the same definition of skeleton for every import).
Now, you can configure each individual animation's properties. Select the animation and go to the "Animation" tab of the Inspector. For most animations you'll want to use Bake Into Pose for transform rotation, position (Y) and position (XZ). For looping animations you'll also want to set them to loop here. These settings are going to depend on exactly what animation you're working with.
In the demo the animations are imported in the Demo > Animations folder.
Create an Animator Controller
Use the Assets > Create > Animator Controller or right-click in the Projects window to create a new animator controller. The Animator controller is where we will build our logic and state machines to control our characters.
In the demo my animator is in the "Demo" folder and is called "DemoAnimatorController".
Create a Controller Script
Mecanim is designed to work with both an animator controller and scripted input such as listening for key presses. We'll do this in a C# script in this example. Create a new script (Assets > Create > C# Script) and name it in a logical manner.
In the demo my script is in the "Demo" folder and is called "DemoControlScript".
It's often easiest to create a prefab of your character so you can quickly add it into new scenes. Generally it's recommended to place a character into a 'container' object so that you can have other associated items (weapons, effects, cameras) all in one game object.
Drag an instance of your character from the Project window into the scene. You'll notice that Unity has already assigned a component to the prefab called Animator. This is placed on by default for any Humanoid or Generic .fbx imports.
With your character in the scene selected use the Inspector to assign the animator controller you created to the "Controller" field of the "Animator" component. This tells the animator where to get it's instructions from.
Create a new empty game object (Game Object > Create Empty) and name it however you'd like to refer to your character's overall container object, such as "Player".
In the Hierarchy window drag the character instance into the container object to make it a child of the container.
Copy the Animator component from the character and paste it onto the container game object then remove the animator component from the character. This setup will allow us to use the animator to animate the character mesh AND use root motion to move the entire container game object.
Add the controller script to the container object. You can do this through "Add Components > Scripts" to find an existing script or drag your script from the Project window onto the Inspector.
If you want to create a basic follow cam you can also drag the main camera from a new scene into the container prefab to make it a child. If you don't have a camera you can create one via the menus by selecting "Game Object > Create Other > Camera". You can also use a more robust camera system you've created or a template camera script from Unity or the Unity Asset Store.
On the container prefab use the Inspector to choose "Add Component > Physics > Character Controller". The character controller is a way for us to add collision detection to our character so they will come with some pre-made physics and will fall with gravity, won't walk through walls, and have other normal behaviour.
Before we turn this into a prefab, we also need to make sure it lines up correctly. Select the container prefab and set it's transform position to 0, 0, 0. Select the character mesh inside of the container and set it's transform position to 0, 0, 0 as well. The pivot of the character should be at it's feet and will now line up perfectly with the prefab container. Position the camera as you'd like to view the character. Mine is set to a behind angle with a transform position of 0, 1.4, -2 and a rotation of 13, 0, 0.
The last step is to align our character controller with our character. Adjust the height and radius to fit the shape of your character and use the Center to move the controller up to fit your character. You may also want to reduce the "Skin Width" which will allow your character to get closer to the ground by reducing the padding between the controller and collision objects.
Finally, to create the prefab, just drag the game object from the hierarchy to the Project window. The final prefabs in the demo are located in the "Demo" folder and are called "Example Character Prefab Alpha" and "Example Character Prefab Beta". You can drag these prefabs into any scene to have a pre-set character ready for use.
We're now ready to begin crafting animations. We'll be working primarily in the Animator Controller and the C# Control Script. To edit the animator controller select it (either by selecting the asset in the Project window OR by selecting a character it is assigned to in your scene) and opening the Window > Animator pane. The Animator window will show a large grid area where we can construct animation states and transitions. To edit the C# script double click on the script in the Project window to open MonoDevelop, the script editor shipped with Unity.
Creating an Idle/Walk with a Blendtree
The first thing we want to do is let our character idle when not moving and walk when we begin moving. Let's first create the animation state. We'll be using a Blendspace for this. In the Animator window right-click anywhere on the grid and select "Create > From New Blendtree". Use the Inspector to name your state.
This creates a new state and assigns it to be the default state. The default state is always in orange and will be the state that your animation starts out in. Double click on the state to view the blend tree. In order to control this blend tree, we'll need a new parameter. In the bottom-left of the Animator Window select the + button in the Parameters tab and create a new Float parameter. I've named it "VSpeed" because it will control the vertical speed of the character (in terms of axis). In the inspector click the + button in the Motion list and select "Add Motion Field". Drag the idle and walking animations to the fields. By default the automated thresholds option will be on or if you manually set it, you can set idle to 0, and walking to 1.
As you drag the parameter slider in the blend tree you can see in the preview window that Unity is blending between the idle and the walk. Now we just need to pass in control of that float via input instead of manually dragging this slider.
Double click your script in the project window to edit it. There are three things we need to do.
First, we need a variable to hold the Animator component so we can talk to it and send instructions. We'll do this by defining a new variable. In my example I made it private because I am only using one script and named it myAnimator. The finished line is
private Animator myAnimator;
Second, inside the Start method, we need to get a reference to the Animator. We could have multiple animated characters, so we need to know which one we're talking to. We have the script attached to the same object as our Animator so we can use the GetComponent method to find the Animator on the same object. The finished line is
myAnimator = GetComponent<Animator>();
Finally, we need to set that VSpeed float based on user input. In this example I'll use "GetAxis", which Unity uses to refers to WASD, arrow keys or joystick input.
We can use GetAxis (which returns a float locked between -1 and 1) to set "VSpeed". 0 will be no input and 1 will be forward input (W, Up Arrow, or Joystick Up) As the joystick, W or up arrow is pressed, VSpeed will increase and the animation will transition from idle to walk. The finished line is
So you can see we are setting the float "VSpeed" located in myAnimator to be equal to the float value of GetAxis. The finished script is here:
When I press play, if I push the W button or the up arrow (or if I had a joystick and used that) the character will transition from the idle to the walk!
You can add more than two animations to a single blendtree. For example, if I had a 'walking backwards' animation, I could set that to be -1 threshold in the blendtree and then the S key, Down Arrow, or joystick down would cause my character to walk backwards without adding any extra code.
In Unity 4.3 or higher you can also create 2-Dimensional blendspaces. For example, you could also create an HSpeed variable and use Input.GetAxis("Horizontal") to control strafing and 45 degree walks all in one single blendtree.
Creating a Transition between States based on a Parameter
We also have some strafing animations we want to add. Let's put them on in a different fashion by creating an individual state for each strafing animation. We want each transition to play a single animation. For this we can drag the animation directly from our project window onto the animator grid to create a new state! Let's also create a new parameter called HSpeed ("Horizontal" speed).
To create the actual transition we want to right click on the IdleWalk blendtree, select "Make Transition" and then click on the state we want to transition into. The transition will be shown by a small white arrow between the states.
Each transition has rules for when it is allowed to occur. The default transition is 'exit time'. That means that as soon as the current animation is done playing, it will transition into the next. We don't want to automatically transition, so instead we're going to transition based on our HSpeed parameter. Click on the transition arrow and the inspector will show some additional information. Towards the bottom you'll see an area called Conditions. These conditions must be met in order for the animation to transition from it's current state into the target state. Change the condition from Exit time to "HSpeed". For this particular transition we want HSpeed to be less than -0.1 because GetAxis uses -1 as Left, 0 as neutral and 1 as right.
Then, from the strafe, we want to return to IdleWalk when HSpeed is GREATER than -0.1 (which is 0 (idle) or greater). We'll set up similar transitions to the right strafing state. In total our transitions are:
- from IdleWalk to LeftStrafe if HSpeed < -0.1
- from LeftStrafe to IdleWalk if HSpeed > -0.1
- from IdleWalk to RightStrafe if HSpeed > 0.1
- from RightStrafe to IdleWalk if HSpeed < 0.1
Now all we need to do is pass in the HSpeed value via our script. Open the C# script again and add a line very similar to the one we used for VSpeed. We're going to set the "HSpeed" float of myAnimator to the value of Input.GetAxis, but this time using horizontal instead of vertical. The finished line is
You can see the total script so far here:
Again, pressing play, we can test this by using the A/D keys or left right arrows to have our character strafe.
Using the Any State to Transition at Any Time
There may be an animation you want to be able to occur at any point in time, no matter what the current state is. Death is a great example. If the player is attacking, idling, or dancing, we want them to die when they are supposed to. Unity provides a state called "Any State". Any animation that transitions from any state is essentially transitioning from ALL states. We'll create a jump animation that lets the character jump whether idling, walking, or strafing.
First, drag the jump animation onto the Animator grid to create a new jump state. We also need a new parameter. This time we'll use a boolean called "Jumping". A boolean is essentially a true or false statement. Yes, or no.
We want to transition from Any State when Jumping is true. Create a transition between Any State and jump and use the Inspector to change the condition from "Exit Time" to "Jumping" is true.
We also need to transition out of jumping back to the IdleWalk blendtree. Create a transition from jump to IdleWalk and leave the condition to exit time. This is because we want to exit jump as soon as the jump animation is over.
The last thing to do is add the jump controls to our script. This is done in a few steps. First, we need to listen for input. We're going to use "Input.GetButtonDown("Jump") to listen for when the jump button is pressed. Unity defines jump as spacebar for PC. The line looks like this:
Inside the brackets we'll create the code we want to trigger when that jump button is pressed. We want to set the animator "Jumping" boolean to be true.
We also want to then wait a second and set the jumping boolean back to false so we don't constantly transition into jump. We can use an Invoke for this. An invoke calls another method after a specified time.
We then need to create the StopJumping method. All that method will do is set the boolean "Jumping" back to false
All together the finished code looks like this:
Now, when we press play we can press the spacebar to trigger a jump. The jump will finish and then transition back to Idle/Walk. You can trigger a jump from anywhere (strafing, idle, walking) because it's connected to the Any State!
This method will work if you're not allowed to jump off of cliffs, but for more advanced jumping and falling you'll want multiple animations (jump start, falling loop, jump land) and want to base the falling and landing state whether you are currently grounded or not.
Adding Conditions to Input
You can combine conditions in your script with conditions in your animator to create animations that will fire only under very specific conditions. For example, we have some turning animations but they are 'in place' turning, so we only want to use it if the character is standing still.
First, let's add the animations to the animator as two new states - left_turn and right_turn and add two new conditions. We'll make these boolean parameters, called TurningLeft and TurningRight.
Next, let's create our transitions. This is pretty straightforward. We want to transition to turn left only if we are currently standing still (so it has to be from IdleWalk) and only if turning left is true. When it's false, we'll go back to IdleWalk. Same for turning right! In total our transitions are:
- from IdleWalk to left_turn if TurningLeft is true
- from left_turn to IdleWalk if TurningLeft is false
- from IdleWalk to right_turn if TurningRight is true
- From right_turn to IdleWalk if TurningRight is false
Back in our script, we now need to listen for some additional input. I'm going to manually assign the Input to be the Q and E keys. When those buttons are pressed and released, we'll toggle TurningLeft and TurningRight respectively to be true and false.
We'll start with finding the input using Input.GetKey("Q"). GetKey means that "while this key is held down" as opposed to "when this key is initially depressed" which is GetKeyDown. Then we also want to check if we're moving. Since we are using the GetAxis to control movement, we can check to see if Horizontal and Vertical are 0. If Q is pressed AND both vertical and horizontal movement are 0, then we'll set TurningLeft to be true.
We also want to add an else statement after the check for the Q key. When the Q key is not beingheld down, we want to set TurningLeft to false.
Pressing Play will have our character transition to a turn animation but only if we're standing still when we press the Q/E keys.
Adding Procedural Motion with Code to an Animation
If you're using the animations provided in the demo you may notice that the turning animation isn't actually turning the character. These particular turns don't include 'root motion'. So far all of our character movement has been handled completely by the animations driving the game object but there may be times your animation doesn't have root motion or you specifically want to control the motion of the character through code.
We're going to add a procedural turn to our character that will let them actually turn while the turn animation is playing AND allow them to turn while walking. This is actually very simple. As long as Q or E is pressed we want to Rotate our current game object. Since we already have a check for the Q and E buttons being pressed, we can nest the rotational code right in there. To rotate we'll just tell our transform to move over time. Turn Left (Q) looks like this:
transform.Rotate(Vector3.down * Time.deltaTime * 100.0f);
and Turn Right (E) looks like this:
transform.Rotate(Vector3.up * Time.deltaTime * 100.0f);
You can use different float values to change the speed of rotation and different Vector3 directionals to change the direction you're rotating. The finished code looks like this:
The final result is that if we press Q or E while standing still our animation will play and we will turn, but we can also now press Q or E while walking and our walk will turn!
If you don't have every single variation of animation you need (turning walks) or need to add your own additional procedural motion on top of an animation, this is a great way to do it.
Using Sub State Machines
Sometimes you may have completely separate animation sets that you want to have their own animation logic. An example could be a 'sneaking' mode. In sneaking mode you might have separate locomotion and additional abilities like stealing or stealth kills. Sub State Machines will let you create a new grid area with it's own logic. We're going to use a sub state machine to add a few actions to our character.
To create a sub state machine right-click anywhere on the animator grid and select "Create Sub State Machine". In the inspector, give the sub state machine a name. I'm calling it "Actions". Sub State machines are represented by a hexagonal blue state.
We also want to create a new parameter. I'm going to use an Int called "CurrentAction". Booleans can get overwhelming when you have a lot of actions, so I can use an int as an identifier for each action in the actions state machine.
You can double click on the Sub State Machine to enter the sub state. Here, we're going to create a new state by dragging our gangnam style dance into the grid.
To create a transition to a state inside a Sub State Machine, click on thestate you want to transition from, then click on the Sub State Machine. From the list, select the state you want to transition into. We're using the CurrentAction integer to define what action is currently being performed. 0 will be "no action", so 1 will be our first action, the dance. Therefore our transition should be from IdleWalk to gangnam_style if CurrentAction is 1.
Similarly, we want to transition out of the dance when CurrentAction is back to 0. This is going to create a toggle effect where we can start and stop dancing.
We'll also need to script that toggle! We'll use the Input.GetKeyDown to check for a key press. I'm using the 1 key. When the button is pressed, we're going to check the state of the Action to be sure no action is being taken (CurrentAction is none / 0 ) and flip it (CurrentAction is dance / 1). If the action is dance/1 we'll flip it to none/0.
The effect is that if we press 1 we will begin dancing. I've imported the dance animation as a looping animation so it will continue to dance indefinitely until we press 1 a second time, creating a toggle.
Transition Animations and Combining Techniques
We're going to combine several of the previous ideas to create a kneeling toggle. This will use a 3 part animation, the idea of toggles, conditional transitions, exit time transitions, and the integer based index of actions.
First, let's add all three animations to the Actions Sub State Machine as three new states. These are kneeling_down (coming from a stand down into a kneeling pose), kneeling idle (a looping animation in the kneeling pose) and kneeling_stand (rising from a kneeling position back into a standing pose).
We want to use a combination of techniques here. We're going to transition from Idle/Walk on the base layer into kneeling_down when CurrentAction is equal to 2. Make sure you check the Inspector for what transition you're editing as the IdleWalk currently has two transitions into the Actions Sub State Machine (the transition line shows this with 3 arrows and the Inspector has a list of transitions).
Then, as soon as kneeling_down animation has finished we want it to transition into kneeling_idle. The total list of transitions we want are
- IdleWalk to kneeling_down if CurrentAction is 2
- kneeling_down to kneeling_idle on Exit Time
- kneeling_idle to kneeling_stand if CurrentAction is 0
- kneeling_stand to IdleWalk on Exit Time
The last thing to do is add the code to check for the Action 2 toggle. This is identical to our check for Action 1, just a different key.
The effect is similar to the dance toggle, but we now play the kneeling down transition then move into the kneeling idle loop. This creates a seamless animation! We'll stay at the kneeling_idle loop until we toggle it off, when we'll play the kneeling_stand transition animation and return to standing.
You can also have multiple layers of animation that affect the layers beneath them. We're going to use a layer to create a wave animation that only plays on the upper body and can be played any time, overriding any animation on the base layer.
The first thing we'll need is an avatar mask. You can create an avatar mask using "Assets > Create > Avatar Body Mask" or Skeleton Mask (skeleton is based off of bones). For the Avatar Body mask, use the Inspector to click the parts you want the mask to use. Green areas will be affected by animation while red areas will not. I chose to make a mask that had one arm with animation and one with out.
Back in our Animator, create a new layer. I've named it "UpperBody". Assign the Human mask to the Avatar Mask we created and set the Blending mode to Override. Override will replace the animation on the lower layers while additive will add the animations together (can be highly unpredictable unless you're an advanced animator). The new layer has an empty state machine.
Let's create an empty state by right-clicking the grid and selecting "Create State > Empty" and name it Empty. Let's also drag our wave animation into the grid. The reason for having an empty animation is because sometimes we need a way for this layer to not be playing the wave animation. So by default, we'll start in empty which has no animation to override the lower layers and lets them play as normal.
Our transitions are fairly simple here! We'll use our actions indexing integer so we want to transition to the wave animation when CurrentAction is 3. The wave isn't looping, so we'll transition out based on exit time.
- From Empty to wave if CurrentAction is 3
- From wave to Empty on Exit Time
Now we'll add the code to trigger the wave! This is similar to some other things we've done. Instead of using GetKey we're going to use GetKeyDown and GetKeyUp. GetKeyDown triggers when a key is depressed and GetKeyUp is triggered when it's released.
We'll first listen for the action key (3) to be pressed and set the CurrentAction parameter to 3 to trigger the animation.
We also need to set the weight of the layer. By default every layer is 0 (even if you use the slider in the Animator) and needs to be set through code. Setting layer weight is done by layer index with base layer being 0, rather than by name, so we'll set "layer 1" to a weight of "1f" (1 being "100% on" and 0 being "100% off).
myAnimator.SetLayerWeight (1, 1f);
Finally, we'll also turn the action off as soon as the key is released.
The final code looks like this:
The final effect is that we can walk and then press 3 to play a wave animation that only affects the upper body.
There is a ton of use for animation layers! You could have a layer that only affects the left arm, and one that affects the right arm for some asynchronous arm action, a layer that affects just the face for facial animation like talking and laughing during combat, or even one that affects just the legs so you can attack with your upper body animations and run with your lower body animations!
You've passed the realm of Mixamo and Unity and are well into advanced animation! We recommend visiting Unity for further advanced training!