# 3. Blend Trees
Part of [[Animation]]. Prev: [[2.States Transitions and Parameters]]. Next: [[4.Layers Masks Root Motion and Events]].
**Docs:** Manual 6000.5 — 1D Blending (thresholds, Automate Thresholds, Compute Thresholds from root motion); 2D blending types (Freeform Cartesian / Directional, Simple Directional, etc. as listed in your Editor's Blend Type dropdown).
## 3.1 What a Blend Tree is
A **Blend Tree** is a state whose "motion" is a weighted mix of child motions (clips or nested blend trees), driven by one or two float parameters. Unlike transitions, blending is continuous — ideal for Speed and MoveX/MoveY locomotion.
Create: right-click Animator graph → **Create State → From New Blend Tree**. Select the state → Inspector → double-click the Blend Tree to edit. Or select the blend tree node and set **Blend Type**.
## 3.2 1D Blend Tree (Speed)
Classic: Idle (0) → Walk (1.5) → Run (4) on parameter `Speed` (m/s or 0–1 normalized).
1. Blend Type: **1D**.
2. Parameter: `Speed`.
3. **+ → Add Motion Field** for each clip.
4. Set **Threshold** per motion, or enable **Automate Thresholds** for even spacing across the parameter range.
5. **Compute Thresholds** dropdown can set thresholds from clip root-motion data: Speed, Velocity X/Y/Z, Angular Speed (Rad/Deg) — verified Manual options. Use when clips already carry honest root motion.
Inspector diagram: blue pyramids = full influence peaks; red bar = live parameter. Scrub in Preview.
```csharp
using UnityEngine;
/// Feeds a 1D Speed blend tree. Prefer real m/s if thresholds came from Compute Thresholds > Speed.
[RequireComponent(typeof(Animator))]
public sealed class SpeedBlendDriver : MonoBehaviour
{
static readonly int SpeedHash = Animator.StringToHash("Speed");
[SerializeField] float damp = 0.15f;
Animator _anim;
void Awake() => _anim = GetComponent<Animator>();
/// planarSpeed: magnitude of horizontal velocity in m/s.
public void Tick(float planarSpeed)
{
_anim.SetFloat(SpeedHash, Mathf.Max(0f, planarSpeed), damp, Time.deltaTime);
}
}
```
**Normalized 0–1 alternative:** thresholds at 0 / 0.5 / 1.0 and feed `planarSpeed / maxRunSpeed`. Easier hand-tuning; worse when swapping clip packs with different authored speeds.
## 3.3 2D Blend Tree (strafe / omni)
For WASD / stick locomotion with strafe clips:
1. Blend Type: pick a **2D** mode from the dropdown (commonly **2D Freeform Directional** or **2D Freeform Cartesian** — use the type that matches how you author positions; confirm labels in your Editor).
2. Parameters: e.g. `MoveX`, `MoveY` in **[-1, 1]** (camera-relative or character-relative).
3. Place motions on the 2D plane: forward `(0,1)`, back `(0,-1)`, left `(-1,0)`, right `(1,0)`, diagonals if you have clips, idle `(0,0)`.
```csharp
using UnityEngine;
[RequireComponent(typeof(Animator))]
public sealed class PlanarBlendDriver : MonoBehaviour
{
static readonly int MoveXHash = Animator.StringToHash("MoveX");
static readonly int MoveYHash = Animator.StringToHash("MoveY");
[SerializeField] float damp = 0.1f;
Animator _anim;
void Awake() => _anim = GetComponent<Animator>();
/// move: character-relative desired planar direction, typically magnitude 0..1.
public void Tick(Vector2 move)
{
_anim.SetFloat(MoveXHash, move.x, damp, Time.deltaTime);
_anim.SetFloat(MoveYHash, move.y, damp, Time.deltaTime);
}
}
```
Pair with [[Surface-Walking with an Omnidirectional Player Movement]] or a standard CharacterController: convert world velocity into local MoveX/MoveY before feeding the tree.
## 3.4 Nested trees and dual-parameter locomotion
Pattern: outer 1D on `Speed` whose children are 2D directional trees at walk and run paces — or the reverse. Keep nesting shallow (2 levels). Each nested tree has its own parameter bindings.
## 3.5 Blend Trees vs transitions
| Use Blend Tree | Use Transition |
|---|---|
| Continuous speed / direction | Discrete jumps, attacks, hit reacts |
| Many clips that must crossfade spatially | Few clips with timing gates (Exit Time) |
| Foot-phase continuity via careful clip authoring | Hard cuts OK |
Jumping usually exits the locomotion blend tree state via a **Jump** trigger transition, then returns on **Grounded**.
## 3.6 Foot sliding quick notes
- Mismatched thresholds vs actual root-motion speed → slide. Prefer Compute Thresholds or measure clip meters/second.
- Blending opposite feet out of phase → use similar gait authoring, or sync cycles (advanced).
- In-place clips + script movement at wrong speed → slide (part 4).
## 3.7 Verified vs unverified
**Verified:** 1D Blend Type, single parameter, motion fields, threshold pyramids, Automate Thresholds, Compute Thresholds options (Manual — 1D Blending).
**Unverified:** exact names/ordering of every 2D Blend Type enum label in 6000.5+ (confirm in Inspector); nested-tree performance cost on Quest ([[Meta Quest 2]]).
**Not compiled:** drivers above.