A character in a game has no fixed timeline. One frame she is standing still; the next the player shoves the stick forward and she must walk, then run, then jam the button and leap. There is no animator sitting behind the console re-timing curves in real time — so the engine needs a small, cheap machine that watches a handful of numbers (speed, "is jump pressed?", "is grounded?") and, sixty times a second, decides which clips to sample and how much of each to mix. That machine is the animation-control layer, and it is built from two ideas that fit together like gears: animation state machines and blend trees.
A state machine answers "which behaviour are we in?" — idle, walk, jump — and how to slide between them. A blend tree answers "inside this behaviour, how do the clips mix?" — 40% walk, 60% run, right now. This page builds both, does the arithmetic of a speed blend by hand, and shows the one bug that ruins them: clips whose feet are out of step.
Picture a graph. Each node is a state — and a state is just "play this
thing": a single clip (Idle, Jump), or a whole
sub-graph (a Locomotion state that is itself a blend tree of walk and
run). Each edge is a transition, and a transition carries three
things: a condition that fires it, a blend duration over which the old state
cross-fades into the new one, and a set of rules about when it is allowed to happen.
jumpPressed == true.
Two transition rules do most of the work. Exit time says
"don't leave until the current clip has played to (say) 90% of its loop" — you use it so a footstep
or an attack swing finishes cleanly instead of snapping mid-stride. Interruption
says whether an in-progress transition can itself be cut short by a higher-priority one — you want a
Hit reaction to interrupt a lazy Idle→Walk fade, but you do not
want a jitter on the speed input to keep re-triggering Walk↔Run every frame.
A state machine is discrete — you are in walk or run. But real locomotion is a continuum: at 2.7 m/s you are neither purely walking nor purely running, you are somewhere between. A blend tree takes one or more continuous parameters and produces a weighted mix of clips whose weights sum to one.
The simplest is a 1D blend space. Place clips along a line by the value of a single
parameter — say walk anchored at
A 2D blend space spreads clips across a plane, most often movement direction × speed: forward, back, and the two strafes at the compass points, with a jog and a sprint further out. The query point — where the stick is pointing, how hard — lands somewhere inside, and the engine hands out weights to the surrounding clips. Common schemes are barycentric weights (the point sits inside a triangle of the three nearest clips) or a gradient band that falls off with distance; either way, the weights are non-negative and sum to one.
Four clips sit at the corners of a movement square: forward vs back on the vertical axis, left vs
right strafe on the horizontal. The dark dot is the blend point set by the two
sliders (how much sideways, how much forward). Its position hands each corner clip a
weight by bilinear interpolation — the fraction of the opposite rectangle's
area — and the four always sum to
The pose you finally send to the skin is
Take a 1D blend between two clips: walk anchored at
Linear interpolation gives the run weight as the fraction of the way from walk to run:
But there is a subtlety that the weight alone doesn't capture. If we sample the walk clip at its
frame 7 and the run clip at its frame 20, their feet may be in totally different parts of the stride.
Before blending, the engine phase-syncs the clips: it treats each loop as a
normalised phase
A character often needs to do two unrelated things simultaneously — walk with the legs
while the upper body waves or reloads. You get this with layers. A
second animation layer runs its own state machine, but a mask (a per-bone weight,
usually 0 or 1) restricts it to a subset of the skeleton: the wave layer has weight
Per-bone weights need not be a hard 0/1 either: feathering the mask weight down across the spine bones blends the boundary so the waving torso doesn't snap rigidly onto the walking hips.
The reason this whole scheme is the industry default is that it is astonishingly cheap. Per frame a blend node samples only its active clips — a 2D blend usually touches three or four, not the dozen in the space — interpolating each sampled joint transform, then takes a weighted average. That is a few pose evaluations plus one blend per bone: a handful of multiply-adds per joint, well under a millisecond for a normal skeleton. No solving, no simulation — just sampling stored curves and mixing them, which is why a crowd of hundreds of characters can each run its own state machine in real time.
In a 2D blend space the three nearest clips form a triangle around the query point, and the natural
weights are its barycentric coordinates — the areas of the three sub-triangles you
get by joining the point to the corners, each divided by the whole area. They are automatically
non-negative inside the triangle and sum to one, which is exactly the "convex combination" property a
pose blend needs (weights outside
The most common blend-tree bug is foot sliding — the character glides as if on ice, or the feet stutter and jitter. Almost always the cause is misaligned foot phase: you are averaging a walk clip in which the left foot is planted with a run clip in which the left foot is in the air. The blend puts the foot at some impossible in-between height, and because the two clips loop at different rates the mismatch drifts, so the plant point slides along the ground.
The fix is that every clip in a blend space must be phase-synchronised: authored (or
retimed) so that the same normalised phase