Game Dev Cheat Sheet

Unity Animator Reference

Animator Controller methods, parameters, layers, and blend trees with C# code.

The Unity Animator Controller drives state machines for character animation, UI transitions, and more. This reference covers the most commonly used Animator methods and patterns with copy-paste C# code, so you can wire up parameters, crossfade between states, and build blend trees without digging through the docs.

Setting Parameters

Animator parameters are the bridge between your C# code and the Animator state machine. Set them to trigger transitions, control blend trees, and drive logic inside the controller.

SetBool

Set a boolean parameter. Commonly used for toggles like isGrounded or isRunning.

animator.SetBool("isRunning", true);

SetTrigger

Fire a trigger parameter. Triggers auto-reset after being consumed by a transition.

animator.SetTrigger("attack");

SetFloat

Set a float parameter. Used for blend trees (speed, direction) and gradual transitions.

// Direct set
animator.SetFloat("speed", currentSpeed);

// Damped set (smooths over time)
animator.SetFloat("speed", targetSpeed, 0.1f, Time.deltaTime);

SetInteger

Set an integer parameter. Useful for weapon index or state enums.

animator.SetInteger("weaponIndex", 2);

ResetTrigger

Manually reset a trigger that may have been set but not yet consumed. Prevents queued triggers from firing unexpectedly.

animator.ResetTrigger("attack");

Crossfade and Direct State Control

Sometimes you need to force the Animator into a specific state rather than letting transitions handle it. Play jumps immediately, while CrossFade blends smoothly. Normalised time runs from 0 (start) to 1 (end) of the clip.

Play

Immediately switch to a state with no blending. Use for instant resets like respawn or teleport.

// Play from the start
animator.Play("Idle");

// Play at a specific normalised time (0.5 = halfway)
animator.Play("Run", 0, 0.5f);

CrossFade

Smoothly blend from the current state to the target over a normalised duration. The duration is a fraction of the target clip length.

// Crossfade over 25% of the target clip's length
animator.CrossFade("Run", 0.25f);

// Crossfade on a specific layer
animator.CrossFade("Run", 0.25f, layerIndex: 1);

CrossFadeInFixedTime

Same as CrossFade but the duration is in seconds rather than normalised time. Easier to reason about when clips have different lengths.

// Crossfade over 0.2 seconds regardless of clip length
animator.CrossFadeInFixedTime("Run", 0.2f);

Getting State Info

Query the Animator to find out which state is currently playing, whether a transition is active, and how far through the current clip the animation has progressed.

GetCurrentAnimatorStateInfo

Returns info about the current state on a given layer, including normalizedTime and state name hash.

AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);

// Check which state is playing
if (stateInfo.IsName("Attack"))
{
    Debug.Log("Currently attacking");
}

// Get normalised progress (0 to 1 per loop)
float progress = stateInfo.normalizedTime % 1f;

IsInTransition

Returns true if the Animator is currently blending between two states on the given layer.

if (animator.IsInTransition(0))
{
    // Wait for the current transition to finish
    return;
}

normalizedTime for Progress

Use normalizedTime to check how far through a clip has played. Values above 1.0 mean the clip has looped.

AnimatorStateInfo info = animator.GetCurrentAnimatorStateInfo(0);

// Has the clip finished at least one full play?
bool hasFinished = info.normalizedTime >= 1.0f;

// Current progress within the loop (0 to 1)
float loopProgress = info.normalizedTime % 1f;

Animator Layers

Layers let you run multiple state machines in parallel. The base layer (index 0) typically handles full-body movement, while additional layers handle upper body overrides, facial expressions, or additive effects. All Set and Get methods accept a layer index parameter.

SetLayerWeight

Control how much a layer contributes. 0 = fully off, 1 = fully on. Blend at runtime for smooth transitions.

// Enable the upper body layer at full weight
animator.SetLayerWeight(1, 1f);

// Smoothly blend a layer on/off
float targetWeight = isShooting ? 1f : 0f;
float current = animator.GetLayerWeight(1);
animator.SetLayerWeight(1, Mathf.Lerp(current, targetWeight, Time.deltaTime * 5f));

Layer Index on Parameters

Pass the layer index to state query methods to check specific layers.

// Check state info on layer 1 (upper body)
AnimatorStateInfo upperInfo = animator.GetCurrentAnimatorStateInfo(1);

// Play a state on a specific layer
animator.Play("Reload", 1);

// Check if layer 1 is in transition
bool transitioning = animator.IsInTransition(1);

Blend Trees

Blend trees smoothly interpolate between multiple animations based on one or two float parameters. You set up the blend tree in the Animator window and drive it from code by setting the float parameters.

1D Blend Tree

Uses a single float parameter to blend between clips. Typical example: speed parameter blending idle, walk, and run.

// Blend tree parameter: "speed"
// Thresholds in Animator: idle=0, walk=0.5, run=1
float speed = rb.linearVelocity.magnitude / maxSpeed;
animator.SetFloat("speed", speed, 0.1f, Time.deltaTime);

2D Blend Tree

Uses two float parameters for omnidirectional movement. Choose Freeform Directional for locomotion or Freeform Cartesian for strafing.

// Blend tree parameters: "velX" and "velY"
Vector3 localVel = transform.InverseTransformDirection(rb.linearVelocity);
animator.SetFloat("velX", localVel.x, 0.1f, Time.deltaTime);
animator.SetFloat("velY", localVel.z, 0.1f, Time.deltaTime);

Avatar Masks

Avatar masks define which bones a layer affects. Assign a mask to a layer in the Animator Controller to limit animations to specific body parts. This lets you play different animations on the upper and lower body simultaneously.

Upper/Lower Body Separation

Create an AvatarMask asset in Unity (Assets > Create > Avatar Mask). Enable only the upper body bones, then assign it to a layer in the Animator Controller. The base layer handles legs (locomotion) while the masked layer handles the torso, arms, and head (shooting, reloading, waving).

// Layer 0 (Base): Full body locomotion (idle, walk, run)
// Layer 1 (Upper Body): Override layer with upper body mask
//   - Assign AvatarMask to this layer in the Animator window
//   - Set blending to Override

// Enable upper body layer when the character equips a weapon
animator.SetLayerWeight(1, 1f);

// The character can now run (layer 0) and aim/shoot (layer 1)
// simultaneously without the animations conflicting

When to Use Avatar Masks

  • Shooting or aiming while running: upper body aims, lower body runs
  • Carrying objects: arms hold the item, legs animate freely
  • Facial expressions: face layer separate from body layer
  • Hit reactions: flinch on the upper body without interrupting movement

Common Patterns

Production-ready patterns that come up in nearly every game using the Animator.

Locomotion Blend Tree

Drive a 1D blend tree from the character's velocity magnitude. Damping the parameter avoids snapping between idle, walk, and run.

void Update()
{
    float speed = rb.linearVelocity.magnitude / maxSpeed;
    animator.SetFloat("speed", speed, 0.15f, Time.deltaTime);

    // Optional: set a grounded bool for jump transitions
    animator.SetBool("isGrounded", isGrounded);
}

Attack Trigger with Return to Idle

Fire a trigger to play the attack clip, then automatically return to idle via a transition with Has Exit Time enabled in the Animator window.

void Attack()
{
    // Reset first to prevent queued triggers
    animator.ResetTrigger("attack");
    animator.SetTrigger("attack");
}

// In the Animator Controller:
// 1. Create transition from Any State -> Attack
//    Condition: attack (trigger)
// 2. Create transition from Attack -> Idle
//    Has Exit Time: true
//    Exit Time: 0.9 (plays 90% of the clip before transitioning)

Death State with normalizedTime Guard

Play a death animation and ensure it only runs once. Check normalizedTime to know when the clip has finished for follow-up logic like ragdoll or respawn.

void Die()
{
    if (isDead) return;
    isDead = true;

    animator.SetTrigger("die");
}

void Update()
{
    if (!isDead) return;

    AnimatorStateInfo info = animator.GetCurrentAnimatorStateInfo(0);
    if (info.IsName("Death") && info.normalizedTime >= 1.0f)
    {
        // Death animation finished
        // Enable ragdoll, show respawn UI, or destroy
        OnDeathAnimationComplete();
    }
}