# 🚶‍♂️ 9. Root Motion

In traditional game development, **Root Motion** allows the animation itself to drive the character's movement in the world. For example, if a character performs a dodge roll or a heavy sword swing that steps forward, the animation moves the actual `GameObject`, preventing foot-sliding and ensuring realistic weight.

Implementing Root Motion in GPU-driven crowds is notoriously difficult because the GPU only moves vertices visually—it doesn't move the actual Entity's `LocalTransform`.

**GPU Animation Entities PRO** solves this by extracting the root motion data during the baking process and evaluating it synchronously on the CPU via Burst-compiled jobs.

Here is how to set it up and use it.

***

#### 🛠️ Step 1: Baking Root Motion

To enable Root Motion, you must tell the Baker to extract the movement data from your Animator Controller.

1. Open the **Animator Baker** window.
2. Assign your source Prefab.
3. In the **Animator** tab, check the box for **Apply Root Motion**.
4. Click **Process**.

**What happens under the hood?**\
The Baker evaluates your animation frame-by-frame, extracts the world-space movement of the root node, and saves it as an array of `RigidTransform` data inside the `BlobAsset`.

***

#### ⚙️ Step 2: How It Works at Runtime

When you spawn your baked DOTS Prefab, it automatically comes with two specific components:

* `AnimatorRootMotionData`: Stores the internal state (last evaluated frame, target animation during transitions, etc.).
* `AnimatorRootMotionDelta`: Stores the actual movement that needs to be applied this frame.

Every frame, the `AnimatorRootMotionSystem` runs on the CPU. It looks at your current animation, your current frame, and your transition weight. It then calculates the exact difference (delta) in position and rotation since the last frame and writes it to the `AnimatorRootMotionDelta` component.

> ✨ **Pro-Tip: Transition Blending**\
> If your character is crossfading between two animations (e.g., transitioning from a Walk to a Run), the system automatically calculates the root motion delta for both animations and blends them together based on the transition weight!

***

#### 🏃 Step 3: Applying the Movement (Default Behavior)

By default, you do not need to write any code to make Root Motion work.

The asset includes a built-in system called `AnimatorRootMotionApplierSystem`. This system runs right before the `TransformSystemGroup`. It reads the `AnimatorRootMotionDelta` and adds it directly to your Entity's `LocalTransform`.

If your game does not use a complex physics engine and you just want your units to move exactly as the animator intended, **you are already done!**

***

#### 🧠 Step 4: Custom Physics & Character Controllers (Advanced)

If you are building a game with Unity Physics, Havok Physics, or a custom Kinematic Character Controller, directly modifying the `LocalTransform` is usually a bad idea. It can cause characters to clip through walls or ignore collisions.

Instead, you want to feed the animation's movement delta into your physics velocity.

**How to do this:**

1. **Disable the Default Applier:**\
   You need to stop our default system from moving the `LocalTransform`. You can do this by adding a system group attribute to your custom code, or simply by removing the `AnimatorRootMotionApplierSystem` from your world initialization.
2. **Read the Delta in your Custom System:**\
   Write your own system that reads the `AnimatorRootMotionDelta` and applies it to your physics components (like `PhysicsVelocity`).

Here is a quick example of how you can read the delta in your own Burst-compiled job:

```csharp
using SnivelerCode.GpuAnimation.Runtime.Components;
using Unity.Burst;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics; // Assuming you are using Unity Physics

[BurstCompile]
[UpdateBefore(typeof(Unity.Physics.Systems.PhysicsSystemGroup))]
public partial struct CustomPhysicsRootMotionJob : IJobEntity
{
    public float DeltaTime;

    private void Execute(ref PhysicsVelocity velocity, ref AnimatorRootMotionDelta rootDelta)
    {
        // 1. Convert the translation delta into a velocity (meters per second)
        float3 animationVelocity = rootDelta.Translation / DeltaTime;

        // 2. Apply it to the physics body (preserving gravity on the Y axis)
        velocity.Linear = new float3(animationVelocity.x, velocity.Linear.y, animationVelocity.z);

        // 3. Clear the delta so it isn't applied twice!
        rootDelta.Translation = float3.zero;
        rootDelta.Rotation = quaternion.identity;
    }
}
```

By taking control of the `AnimatorRootMotionDelta`, you get the best of both worlds: AAA-quality animation-driven movement, perfectly integrated with your custom DOTS physics logic.

***

<br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sniveler-code.gitbook.io/dots/gpu-animation-entities-pro/9.-root-motion.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
