Motion Matching (MxM) for Unity
Operational Compendium and Technical Analysis
Table of Contents
- Executive Summary
- Theoretical Framework
- Installation & Environment Configuration
- MxM Architecture
- Runtime Mechanics
- Trajectory Logic & Input Profiles
- Asset Preparation
- The Event System
- Integration with Game Systems
- Advanced Configuration
- Troubleshooting
- Conclusion
1. Executive Summary
The Paradigm Shift in Real-Time Animation
The domain of real-time character animation has stood on the precipice of a fundamental paradigm shift for the better part of a decade. For over twenty years, the industry standard has been the Finite State Machine (FSM)—represented in Unity by the Mecanim system.
┌─────────────────────────────────────────────────────────────────┐
│ TRADITIONAL FSM MODEL │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ Idle │──────│ Walk │──────│ Run │──────│ Jump │ │
│ └──────┘ └──────┘ └──────┘ └──────┘ │
│ │ │ │ │ │
│ └────────────┴────────────┴────────────┘ │
│ Explicit Transitions │
│ │
└─────────────────────────────────────────────────────────────────┘
In this deterministic model, animators and gameplay programmers explicitly construct graphs where: - Nodes represent static animation clips (e.g., Idle, Run, Jump) - Edges represent the transitional logic connecting them
The Scalability Problem
While functional for simple behaviors, the FSM model scales poorly:
| Issue | Impact |
|---|---|
| State Explosion | Number of required states grows exponentially with character fidelity |
| "Spaghetti Graphs" | Difficult to debug and maintain |
| Rigid Transitions | Cross-fading fails to account for momentum, foot placement, or current pose |
The Motion Matching Solution
Motion Matching (MxM) represents the abandonment of explicit graph-based logic in favor of a data-driven, declarative approach.
┌─────────────────────────────────────────────────────────────────┐
│ MOTION MATCHING MODEL │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌──────────────────────┐ │
│ │ INTENT │ ──── Search ────── │ Animation Database │ │
│ │ (Trajectory │ ↓ │ ┌────┬────┬────┐ │ │
│ │ + Action) │ Best Match │ │ F1 │ F2 │ F3 │... │ │
│ └─────────────┘ ↓ │ └────┴────┴────┘ │ │
│ ┌──────────┐ └──────────────────────┘ │
│ │ Optimal │ │
│ │ Frame │ │
│ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Instead of defining how a character transitions from State A to State B, the developer defines the intent—the desired trajectory and action—and the system algorithmically selects the optimal frame.
This technology, popularized by AAA titles such as The Last of Us Part II and For Honor, shifts the burden of quality from the logic graph to the data coverage.
About MxM for Unity
The "Motion Matching for Unity" (MxM) asset, developed by Kenneth Claassen (Vault Break Studios), is the premier implementation for the Unity engine. It leverages Unity's Data-Oriented Technology Stack (DOTS):
- Burst Compiler - Native code compilation
- C# Jobs System - Multi-threaded execution
This enables computationally expensive "nearest neighbor" searches in real-time on consumer hardware.
2. Theoretical Framework of Motion Matching
To operate MxM effectively, one must understand the underlying algorithmic logic that drives the system's decision-making process.
2.1 The Core Algorithm: Trajectory and Pose Matching
In a traditional state machine, the system waits for a boolean condition (e.g., IsRunning = true) to trigger a transition. In Motion Matching, the system evaluates the character's state every frame against a database of possible future states.
This evaluation is governed by a Cost Function, which calculates an error value for jumping to a new frame compared to continuing the current one.
COST FUNCTION
┌──────────────────────────────────┐
│ │
│ Total Cost = Pose Cost │
│ + Trajectory Cost │
│ │
│ Goal: MINIMIZE Total Cost │
│ │
└──────────────────────────────────┘
Pose Cost
Measures the geometric difference between the character's current skeletal pose and a candidate pose in the database:
- Joint positions
- Rotations
- Velocities
High pose cost → Visual artifacts like "popping" (limbs teleporting) or foot sliding
Trajectory Cost
Measures the difference between input intent and animation path:
- Desired Trajectory → Where the player wants to go (joystick input)
- Animation Trajectory → Where the character actually goes in the clip
If the player pushes left, animations where the actor turns right will have prohibitively high trajectory cost and will be discarded.
2.2 The Role of Inertialization
Traditional Mecanim transitions rely on cross-fading:
Traditional Cross-Fade:
Clip A: ████████░░░░░░░░
Clip B: ░░░░░░░░████████
Result: Blended over time (slow, floaty)
MxM utilizes Inertialization (advanced inertial blending):
Inertial Blending:
Source Pose ──┬── Velocity Difference ──┬── Spring-Damper Decay
│ (Inertial Error) │
Target Pose ──┘ └── Instant Transition
(preserves momentum)
Benefits: - Instant transitions without visual jar - Preserves momentum and responsiveness - Critical for action-oriented gameplay
2.3 The "Dance Card" Concept
The shift to Motion Matching necessitates a change in asset creation philosophy.
| FSM Approach | Motion Matching Approach |
|---|---|
| Discrete loops: "Run", "Walk", "Turn" | Dance Cards: Long continuous recordings |
| Short, isolated clips | Wide variety of movements in single stream |
| State-per-action | Coverage-based |
Effective Dance Card for Locomotion
┌────────────────────────────────────────────────────────────────┐
│ DANCE CARD COVERAGE │
├────────────────────────────────────────────────────────────────┤
│ │
│ Starts from idle: Stops from running: │
│ ↗ ↑ ↖ ↗ ↑ ↖ │
│ → · ← → · ← │
│ ↘ ↓ ↙ ↘ ↓ ↙ │
│ (all 8 directions) (all 8 directions) │
│ │
│ Continuous running: Direction changes: │
│ ∞ (figure-8s) ↱ 90° plants │
│ 〜 (weaves) ↱ 135° pivots │
│ ⟨ (sharp turns) ↱ 180° pivots │
│ │
└────────────────────────────────────────────────────────────────┘
Critical Insight: If the database lacks a specific movement (e.g., 90° sharp right turn while sprinting), the system cannot match it. The character will feel unresponsive or "boaty."
3. Installation and Environment Configuration
The installation of MxM is non-trivial compared to standard assets. It acts as a middleware layer on top of Unity's DOTS.
3.1 Unity Version Compatibility
This community fork maintains compatibility with modern Unity versions:
| Version | Recommendation |
|---|---|
| Minimum | Unity 2020.3 LTS |
| Recommended | Unity 2022.3 LTS or newer |
⚠️ Warning: Avoid using Unity Beta versions for production with MxM, as Jobs/Burst APIs can be volatile. This is the official, single source of truth for version compatibility.
3.2 Mandatory Package Dependencies
MxM requires specific packages from the Unity Package Manager (UPM):
| Package | Package ID | Criticality | Function |
|---|---|---|---|
| Mathematics | com.unity.mathematics |
Critical | Optimized vector types (float3, quaternion) for SIMD operations |
| Collections | com.unity.collections |
Critical | Unmanaged memory structures (NativeArray, NativeList) for Jobs |
| Burst | com.unity.burst |
High | Compiles C# jobs to optimized native code (LLVM) |
| Jobs | com.unity.jobs |
Critical | Manages worker threads for parallel search |
Note: In Unity 2021+,
com.unity.jobsmay be integrated into core or Burst. IfIJobParallelForerrors appear, manually verify installation.
3.3 Locating the Official Documentation
The official documentation is embedded locally:
Assets/Plugins/Motion Matching/Documentation/
├── UserManual.pdf # Comprehensive reference
├── QuickStartGuide.pdf # Basic setup walkthrough
└── AnimationGuide.pdf # Mocap data requirements
Tip: PDFs contain hyperlinks to Google Docs "Live Versions" which are updated in real-time with API changes and patch notes.
4. The MxM Architecture: Data Structures and Pipeline
The architecture is bifurcated into two distinct phases:
┌─────────────────────────────────────────────────────────────────┐
│ MxM ARCHITECTURE │
├────────────────────────────┬────────────────────────────────────┤
│ OFFLINE (Editor) │ ONLINE (Runtime) │
├────────────────────────────┼────────────────────────────────────┤
│ │ │
│ .anim files │ MxMAnimator │
│ ↓ │ ↓ │
│ Pre-Processing │ Jobs System │
│ ↓ │ ↓ │
│ MMData Asset ──────────────────→ Search Query │
│ (Binary Database) │ ↓ │
│ │ Best Match Frame │
│ │ ↓ │
│ │ Inertial Blend │
│ │ ↓ │
│ │ Final Pose │
│ │ │
└────────────────────────────┴────────────────────────────────────┘
4.1 The MMData Asset: The Brain of the System
Unlike Mecanim (which references .anim clips directly), MxM converts animation data into a highly optimized binary format: MMData (ScriptableObject).
MMData contains:
| Component | Description |
|---|---|
| Pose Database | Flattened array of joint positions/rotations for every valid frame |
| Trajectory Database | Pre-calculated prediction paths for every frame |
| Feature Vectors | Optimized numerical representations for search |
| Acceleration Structures | KD-trees for fast candidate filtering |
4.2 Composites: Organizing Unstructured Data
Composites are logical groupings of animation clips that share a specific function or context.
┌─────────────────────────────────────────┐
│ COMPOSITE: "Locomotion" │
├─────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌───────────┐ │
│ │ Run_Fwd │ │Run_Left │ │Walk_Circle│ │
│ └─────────┘ └─────────┘ └───────────┘ │
│ │
│ Bulk Settings: Rotation Offset, Tags │
└─────────────────────────────────────────┘
Composite Categories: - Standard - Continuous locomotion - Events - Discrete actions (attacks, interactions) - Clips - Specific one-off animations
4.3 The Pre-Processing Pipeline Steps
The workflow is strictly sequential:
Step 1: Skeleton Definition
│
▼
Step 2: Clip Import & Categorization
│
▼
Step 3: Tagging
│
▼
Step 4: Processing (Baking)
│
▼
Step 5: Validation
Step 1: Skeleton Definition
Select joints critical for matching:
| Setup Level | Joints |
|---|---|
| Standard | Hips (Root), Left Foot, Right Foot |
| High Fidelity | + Shoulders, Hands (for climbing/parkour) |
⚠️ Warning: Adding too many joints increases "Pose Cost" calculation time.
Step 2-3: Clip Import & Tagging
- Drag raw
.animfiles into Composites - Apply semantic tags:
"Crouch","Combat","Indoor"
Step 4-5: Processing & Validation
- Click "Process" to extract velocity and trajectory data
- Red clips indicate looping errors or root motion discontinuities
⚠️ Critical: If an animator modifies a clip and re-imports, the MMData is immediately stale. Re-process to avoid "ghosting" issues.
5. Runtime Mechanics: The MxMAnimator
The runtime logic is encapsulated in the MxMAnimator component, which replaces Mecanim's logic while still using the Animator for mesh skinning.
5.1 The Update Loop
┌──────────────────────────────────────────────────────────────┐
│ MxM UPDATE LOOP │
├──────────────────────────────────────────────────────────────┤
│ │
│ 1. INPUT COLLECTION │
│ └── Poll MxMTrajectoryGenerator for "Desired Trajectory"│
│ ↓ │
│ 2. SEARCH LOGIC │
│ ├── Pass current pose + trajectory to Jobs System │
│ ├── Worker thread queries MMData KD-tree │
│ ├── Filter by active Tags │
│ └── Return "Best Match" frame index │
│ ↓ │
│ 3. BLENDING │
│ ├── Same clip? → Natural Playback (advance frame) │
│ └── Different clip? → Inertial Blend │
│ ↓ │
│ 4. POSE APPLICATION │
│ └── Apply final blended pose to character hierarchy │
│ │
└──────────────────────────────────────────────────────────────┘
5.2 Configuration Parameters
| Parameter | Description | Typical Values |
|---|---|---|
| Playback Speed | Global animation speed multiplier | 1.0 |
| Blend Time | Duration for inertial blends | 0.2s - 0.4s |
| Search Frequency | How often to search (optimization) | Every 1-3 frames |
Tuning Tip: Lower blend time = snappier but may jitter. Higher = smoother but unresponsive.
6. Trajectory Logic and Input Profiles
The "magic" of motion matching lies in Trajectory Prediction—the system looks at where the character wants to be in the future.
6.1 The MxMTrajectoryGenerator
This component translates raw input (Vector2) into a sophisticated path prediction.
┌─────────────────────────────────────────────────────────────────┐
│ TRAJECTORY PREDICTION │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Input (Joystick) │
│ ↓ │
│ ┌─────────────────────┐ │
│ │ Trajectory Generator │ │
│ │ • Max Speed │ │
│ │ • Acceleration │ │
│ │ • Turn Rate │ │
│ └─────────────────────┘ │
│ ↓ │
│ Prediction Points: 0.33s, 0.66s, 1.0s │
│ ↓ │
│ ┌─────────────────────────────────────────┐ │
│ │ · · · · · · · ● │ ← Goal Trajectory │
│ │ ○ │ │
│ │ ↑ Character │ │
│ └─────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
The Disconnect Problem
┌────────────────────────────────────────────────────────────────┐
│ TRAJECTORY MISMATCH │
├────────────────────────────────────────────────────────────────┤
│ │
│ Generator: Turn 180° in 0.1s ← TOO FAST │
│ Animation: Turn 180° in 0.5s │
│ │
│ Result: │
│ ┌──────────────────────────────────────┐ │
│ │ ─ ─ ─ ─ ─ → (Red: Desired) │ │
│ │ ~~~→ (Green: Actual) │ │
│ │ ↑ DIVERGENCE = Foot sliding │ │
│ └──────────────────────────────────────┘ │
│ │
│ Solution: Match generator physics to captured actor physics │
│ │
└────────────────────────────────────────────────────────────────┘
6.2 Input Profiles: Shaping the Future
Input Profiles are ScriptableObjects that override Trajectory Generator settings for specific gameplay contexts.
Example: The Tightrope
Trigger: Character steps onto narrow beam
↓
Swap to "Beam_Profile":
• Max Turn Rate → Near zero
• Bias → Forward only
↓
Generated Trajectory → Straight line
↓
Motion Matching → Filters out turning animations
↓
Result: Only "straight walk" or "balance" animations selected
This enables gameplay-driven filtering without explicit state machine logic.
7. Asset Preparation: The Art of Mocap for MxM
The quality of an MxM character is inextricably linked to the quality of the source data. MxM exposes gaps in data mercilessly.
7.1 Recording the "Dance Card"
Create a continuous sequence designed to cover the Input Space:
┌─────────────────────────────────────────────────────────────────┐
│ RECOMMENDED DANCE CARD STRUCTURE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. IDLE │
│ └── Stand still 5-10 seconds (breathing) │
│ │
│ 2. STARTS │
│ └── From Idle → Walk in 8 cardinal directions │
│ └── Return to Idle each time │
│ │
│ 3. STOPS │
│ └── Walk → Stop (repeat for Run, Sprint) │
│ │
│ 4. LOCOMOTION │
│ ├── Walk: Large Figure-8 (gentle turns) │
│ ├── Walk: Tight slalom (sharp turns) │
│ └── Repeat for Run and Sprint │
│ │
│ 5. PLANTS & PIVOTS │
│ └── Sprint → Plant → Turn 90°, 135°, 180° │
│ │
│ 6. ARCS │
│ └── Run in circles: 2m, 5m, 10m radius │
│ │
└─────────────────────────────────────────────────────────────────┘
7.2 Data Cleaning and Root Motion
MxM relies entirely on Root Motion. The root bone must move with the character.
The "Mixamo Problem"
PROBLEM:
Mixamo animations bake translation into Hips
Root stays static at (0,0,0)
→ MxM breaks
FIX (Unity Import Settings):
1. Rig → Humanoid
2. Animation → Root Transform Rotation
└── Based Upon: Original (not "Body Orientation")
3. Root Transform Position (Y)
└── Based Upon: Feet
If animation still lacks root motion, use external tools (Blender or "Root Motion Fixer" scripts).
7.3 Calibration Handles
Configure reference values that normalize the cost function:
| Handle | Purpose | Example |
|---|---|---|
| Velocity Handle | Maximum character speed | 6 m/s |
| Angular Handle | Maximum turn rate | 180 deg/s |
Why this matters: Without normalization, one cost type may overwhelm the other. Incorrect Velocity Handle can cause the system to refuse blending between Walk and Run.
8. The Event System: Hybrid Determinism
While Motion Matching excels at continuous locomotion, games require discrete, logic-driven actions. MxM solves this with its Event System.
8.1 Anatomy of an Event
An MxM Event is segmented into four critical phases:
┌──────────────────────────────────────────────────────────────────┐
│ EVENT PHASES │
├────────────┬───────────┬───────────────┬─────────────────────────┤
│ WIND-UP │ ACTION │ FOLLOW-THROUGH│ RECOVERY │
├────────────┼───────────┼───────────────┼─────────────────────────┤
│ │ │ │ │
│ ~~~▶│ │ ████████ │ │~~~~~~~~ │ ~~~~~~~~▶ locomotion │
│ │ │ │ │
│ Blend │ Mandatory │ Buffer │ Can be interrupted │
│ from any │ playback │ zone │ for early exit │
│ pose │ │ │ │
│ │ │ │ │
└────────────┴───────────┴───────────────┴─────────────────────────┘
| Phase | Description | Mechanism |
|---|---|---|
| 1. Wind-Up | Transition into the action | System searches for best "entry frame" to blend from current pose |
| 2. Action | Core, compulsory animation | Motion matching suspended; plays to completion |
| 3. Follow-Through | Energy dissipation | Mandatory buffer zone |
| 4. Recovery | Return to locomotion | Can be interrupted; supports "Exit with Motion" |
8.2 Setup Workflow
Step 1: Tag as "Do Not Use"
PRE-PROCESSOR:
Event animations → Add to Composite → Tag as "Do Not Use"
WHY:
Without tag, locomotion search might accidentally pick
a sword swing frame because the foot position matched!
→ Character randomly twitches into attacks while walking
Step 2: Timeline Configuration
MxM Timeline Editor:
├── Drag markers for Wind-Up/Action/Follow-Through/Recovery
└── Assign Event ID (integer)
Step 3: Create Event Definition Asset
EventDefinition (ScriptableObject):
• Priority → Can this interrupt other events?
• Exit with Motion → Blend to Run or Idle?
• Match Target → World-space contact settings
Step 4: Trigger via Script
8.3 Motion Warping and Contact Points
For precision events (e.g., parkour vaulting):
┌─────────────────────────────────────────────────────────────────┐
│ MOTION WARPING │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Animation Point: Hand on vault (local space) │
│ ↕ Correspondence │
│ World Point: Edge of wall (world space) │
│ │
│ During Action phase: │
│ └── Root motion dynamically scaled (stretched/compressed) │
│ └── Character arrives at target location at target time │
│ │
│ Result: Single "Vault" animation works on varying wall sizes │
│ │
└─────────────────────────────────────────────────────────────────┘
9. Integration with Game Systems
MxM drives the root but must coexist with physics, AI, and IK systems.
9.1 Kinematic Character Controllers (KCC)
MxM pairs best with Kinematic Character Controllers, not Rigidbodies.
┌─────────────────────────────────────────────────────────────────┐
│ KCC INTEGRATION │
├─────────────────────────────────────────────────────────────────┤
│ │
│ MxMAnimator │
│ │ │
│ ├── Calculate "Root Motion Delta" │
│ │ │
│ ├── Fire OnUpdateMove event ──────┐ │
│ │ │ │
│ │ ▼ │
│ │ KCC Script │
│ │ │ │
│ │ ├── Attempt move by delta │
│ │ ├── Check collisions │
│ │ │ │
│ │◀─── Feed actual velocity ────┘ │
│ │ back to MxM │
│ │ │
└───────┴─────────────────────────────────────────────────────────┘
Critical: KCC must feed actual velocity back to MxM. Otherwise, MxM thinks the character is still moving and plays "Run" while pushing against a wall.
9.2 AI and NavMesh
For NPCs, input comes from NavMeshAgent instead of joystick:
// Disable automatic NavMeshAgent movement
agent.updatePosition = false;
agent.updateRotation = false;
// Adapter script calculates input vector from next position
Vector3 inputVector = (agent.nextPosition - transform.position).normalized;
// Feed to MxMTrajectoryGenerator
trajectoryGenerator.SetInput(inputVector);
// MxM handles actual movement
9.3 Inverse Kinematics (IK)
Motion matching is accurate but not perfect. Foot sliding occurs on uneven terrain.
PIPELINE ORDER:
MxM applies pose → IK pass (Final IK Grounder) → Snap to geometry
EVENT IK:
MxM gets hand close → Interaction System locks hand to prop
10. Advanced Configuration: Tags, Layers, and Masking
As the database grows, efficiency and logic require segmentation.
10.1 Tagging and "Favour Tags"
| Tag Type | Behavior | Example |
|---|---|---|
| Required Tags | "Must have this tag" | Player presses Crouch → Add "Crouch" requirement → Filter out all Standing animations |
| Favour Tags | "Prefer this tag" | "Injured" state → Try to find "Injured" animations → Fall back to "Neutral" if not available |
Favour Tags provide soft constraints that maintain playability over strict visual accuracy.
10.2 Blend Spaces and Layers
MxM supports Blend Spaces running on top of motion matching:
┌─────────────────────────────────────────────────────────────────┐
│ LAYERED ANIMATION │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Upper Body: Aim Blend Space (controlled by look input) │
│ └── Body Mask: Spine + Arms only │
│ │
│ Lower Body: Motion Matching (legs, feet, hips) │
│ │
│ Use Case: Aiming a weapon while running │
│ │
└─────────────────────────────────────────────────────────────────┘
11. Troubleshooting and Common Pitfalls
11.1 The "Pink Material" / Shader Errors
| Cause | Fix |
|---|---|
| MxM sample materials don't match project Render Pipeline | Use Render Pipeline Converter or material upgrade tools |
MxM code is pipeline-agnostic; only demo assets need conversion.
11.2 Character Sliding / "Ice Skating"
| Cause | Fix |
|---|---|
| A: Trajectory Generator acceleration too high | Lower Max Acceleration in Trajectory settings |
| B: Missing Root Motion | Check import settings (see Section 7.2) |
| C: Poor Calibration | Re-run Calibration tool; ensure Velocity Handle matches sprint speed |
11.3 Burst Compiler Errors
Symptom: Performance is terrible (5ms+ per frame). Console shows "Burst failed to compile."
Fix:
1. Check Burst package version
2. Update to latest stable release
3. Ensure no package conflicts in Unity.Jobs namespace
11.4 "Ghosting" in Editor
Symptom: Character mesh separates from skeleton or flickers.
Cause: MMData is out of sync with source clips.
Fix: Re-bake the MMData in the Pre-Processor.
12. Conclusion and Future Outlook
Motion Matching for Unity (MxM) represents a democratization of AAA animation technology. It offers a solution to the scalability crisis of FSMs by treating animation as a database search problem.
Trade-offs
| Advantage | Challenge |
|---|---|
| Eliminates state machine complexity | Steeper technical learning curve |
| Data-driven quality | Requires high-quality, pre-cleaned animation data |
| AAA-level responsiveness | Not "plug-and-play" for low-fidelity assets |
| Scales with data, not logic | Pipeline commitment required |
The Future: Learned Motion Matching
┌─────────────────────────────────────────────────────────────────┐
│ EVOLUTION PATH │
├─────────────────────────────────────────────────────────────────┤
│ │
│ CURRENT: Classic Search │
│ └── Animation Database (100s MB) │
│ └── KD-Tree Nearest Neighbor │
│ │
│ FUTURE: Learned Motion Matching │
│ └── Neural Network (MBs) │
│ └── Predicts next pose │
│ └── MxM's DOTS architecture ready for ML inference │
│ │
└─────────────────────────────────────────────────────────────────┘
For the contemporary Unity developer, MxM remains the most robust, production-ready solution for high-fidelity character locomotion, bridging the gap between indie resources and blockbuster execution.
Generated from aggregated technical data including video tutorials, forum discussions, and release notes.