Overview
Moving 3D characters requires more than just rigging models and creating animation clips. You need a system that switches between appropriate animations at the right times based on player input and game state—from "Idle" to "Walk," from "Walk" to "Run," and from any state to "Jump." The Animator Controller manages this complex state transition logic.
Animator Controllers are powerful tools for building state machines that visually arrange animation clips as "states" and connect them with "transitions." While 2D animations use similar systems, 3D—especially with Humanoid rigs—offers more advanced and flexible features.
This article covers the basic workflow for managing 3D character actions (idle, walk, run) with Animator Controllers.
The Importance of Humanoid Rigs and Avatars
When discussing 3D character animation, understanding Humanoid rigs and the Avatar system is essential. Setting Animation Type to Humanoid in a model's import settings (Rig tab) generates an Avatar asset that maps the model's skeleton to a standardized humanoid bone structure.
This Avatar enables animation retargeting—reusing animations across completely different models. A "walk" animation created for one character can be applied directly to another character with different proportions. This is incredibly powerful for using Asset Store animations or sharing animations within teams.
Building an Animator Controller
Step 1: Define Parameters
First, define parameters as "variables" to control animation state from scripts. For character movement, you need at least a parameter controlling movement speed.
- Open the Animator window and select the
Parameterstab. - Click
+and create twoFloatparameters:ForwardSpeed: Represents forward/backward movement speed.RightSpeed: Represents left/right movement speed.
Step 2: Smooth Movement with Blend Trees
For smooth animation transitions based on character speed—like between Idle, Walk, and Run—creating individual states connected by transitions becomes tedious. Blend Trees are ideal for handling such continuous variations.
- Right-click in empty space in the Animator window and select
Create State > From New Blend Tree. - Double-click the created Blend Tree state to enter edit mode.
- Select the Blend Tree and change
Blend Typeto2D Freeform Cartesianin Inspector. This enables blending animations using two parameters (X axis:RightSpeed, Y axis:ForwardSpeed). - Click
Add Motion Fieldand register animation clips for each movement:Pos X: 0, Pos Y: 0: Idle animationPos X: 0, Pos Y: 0.5: Walk Forward animationPos X: 0, Pos Y: 1: Run Forward animationPos X: 1, Pos Y: 0: Strafe Right animationPos X: -1, Pos Y: 0: Strafe Left animation
Now animations automatically blend smoothly based on ForwardSpeed and RightSpeed values. For example, ForwardSpeed of 0.75 produces a "brisk walk" blending walk and run animations equally.
Step 3: Layers and Avatar Masks
For more complex control, Animator Controllers support Layers. Use layers when playing different animations on upper body (wielding weapons) and lower body (walking, running).
- Add a new layer with the
+button in theLayerstab. - Set
Weightto1and configureBlendingtoOverrideorAdditivevia the gear icon. - Create an
Avatar Maskspecifying which body parts this layer affects (e.g., upper body only).
This enables compound actions like "reloading while running."
Script Control
Finally, calculate character movement from script and pass values to Animator parameters.
using UnityEngine;
[RequireComponent(typeof(Animator))]
public class CharacterAnimatorController : MonoBehaviour
{
private Animator animator;
// Pre-hash parameter names for faster, safer access
private readonly int forwardSpeedHash = Animator.StringToHash("ForwardSpeed");
private readonly int rightSpeedHash = Animator.StringToHash("RightSpeed");
void Start()
{
animator = GetComponent<Animator>();
}
void Update()
{
// Get movement input (-1.0f to 1.0f range)
float horizontalInput = Input.GetAxis("Horizontal"); // A, D keys
float verticalInput = Input.GetAxis("Vertical"); // W, S keys
// Update Animator parameters
// Using dampTime (3rd argument) in SetFloat smooths value changes for natural transitions
animator.SetFloat(forwardSpeedHash, verticalInput, 0.1f, Time.deltaTime);
animator.SetFloat(rightSpeedHash, horizontalInput, 0.1f, Time.deltaTime);
}
}
Summary
The Animator Controller is the heart of 3D character animation.
Humanoidrigs andAvatarsenable animation reuse.Animator Controlleris the tool for building animation state machines.- Use
Blend Treesfor continuous states like speed to easily implement smooth animation transitions. - Use
LayersandAvatar Masksto play different animations on upper and lower body. - Update parameters with
SetFloatand similar methods from scripts to control animations.
Combining these features creates convincing character movements that respond dynamically to player input.