Quick answer: Turn on Apply Root Motion in the Animator. For CharacterController-based movement, add OnAnimatorMove that forwards animator.deltaPosition to CharacterController.Move. Verify the clip’s Root Transform settings in the import Inspector.

Here is how to fix Unity Animator root motion not applied. You import a beautiful animated walk cycle. In the preview window, the character moves forward naturally. In the scene, the character does the walk motion in place, never moving. Root motion is the system where the animation itself drives position — pro-quality character movement depends on it — but getting it from import to scene involves three settings that must all agree.

The Symptom

An imported character animation plays correctly but the character’s transform does not move. Walking animations look like marching in place. Attack animations play but the character does not lunge forward. In the Animation window preview, root motion visibly affects the character; in the scene, it does not.

Variant: rotation works but translation does not (or vice versa). Another variant: root motion works the first time then stops after a state transition. Another: root motion applies but the character sinks into the floor or flies off the ground.

What Causes This

Apply Root Motion unchecked. The Animator component has an “Apply Root Motion” toggle. When unchecked, animator.deltaPosition and animator.deltaRotation still fire but nothing applies them to the transform. Default for new Animators is checked, but if the character was set up with a CharacterController, the toggle is sometimes turned off to avoid double-motion.

Root motion not baked. The animation clip’s Root Transform Position settings control how root motion is extracted from the animation. If Bake Into Pose is enabled, the motion is “baked” into the pose and does not produce root motion — it produces in-place animation. Useful for keeping feet grounded but defeats root motion.

Wrong Root Node. For Generic rigs, the Root Node dropdown in the Animator Avatar determines which bone drives root motion. If set to None, there is no root motion. For Humanoid rigs, the hips bone is the implicit root.

OnAnimatorMove override without action. Implementing OnAnimatorMove on any MonoBehaviour attached to the Animator’s GameObject overrides the default root motion behavior. If your implementation does not apply the motion (e.g. forgot to call transform.position += animator.deltaPosition), the character stays still.

CharacterController grounded check conflict. With a CharacterController, root motion needs CharacterController.Move to apply. If you apply root motion to the transform directly while also using CharacterController.Move for gravity, the results can cancel or conflict, and some motions appear missing.

The Fix

Step 1: Toggle Apply Root Motion correctly. If you do not have a CharacterController or Rigidbody-based movement script, check Apply Root Motion. The transform updates automatically.

If you do have a custom movement system, uncheck Apply Root Motion only if you plan to read motion manually via OnAnimatorMove. Do not leave it unchecked without OnAnimatorMove — that is the “no motion at all” state.

Step 2: Configure the animation clip. Select the clip or FBX asset in the Project window. In the Inspector, go to the Animation tab and select the clip. Expand Root Transform Position (Y) and (XZ):

For Y (vertical), Bake Into Pose should usually be checked to prevent jumping animations from moving the character on the Y axis (CharacterController handles gravity). For XZ, Bake Into Pose should be unchecked to allow horizontal movement.

Step 3: Implement OnAnimatorMove for CharacterController. If using CharacterController, bridge root motion to the controller:

using UnityEngine;

[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(CharacterController))]
public class RootMotionToController : MonoBehaviour
{
    private Animator animator;
    private CharacterController cc;

    void Awake()
    {
        animator = GetComponent<Animator>();
        cc = GetComponent<CharacterController>();
    }

    void OnAnimatorMove()
    {
        if (Time.deltaTime > 0)
        {
            Vector3 velocity = animator.deltaPosition / Time.deltaTime;
            velocity.y = cc.velocity.y; // preserve gravity
            cc.Move(velocity * Time.deltaTime);
            transform.rotation *= animator.deltaRotation;
        }
    }
}

Keep Apply Root Motion checked — that is what makes OnAnimatorMove fire. Uncheck and the method is never called.

Step 4: Confirm avatar root mapping. For Humanoid rigs, the avatar’s hips is automatically the root. For Generic rigs, set Animator > Avatar > Root Node to the correct bone (usually the top-level bone of your skeleton, not the GameObject’s root).

Debugging Tips

Log root motion values to see what the animator actually outputs:

void OnAnimatorMove()
{
    Debug.Log($"deltaPos={animator.deltaPosition}, " +
        $"deltaRot={animator.deltaRotation.eulerAngles}");
    transform.position += animator.deltaPosition;
    transform.rotation *= animator.deltaRotation;
}

If deltaPosition is near zero while a motion animation is playing, the clip’s Bake Into Pose is enabled or the clip has no baked motion. If the log never fires, Apply Root Motion is off. If the log fires with proper values but the character does not move, something else is resetting the position — check for rigidbody constraints, other scripts assigning to transform.position, or parenting issues.

Blend Tree Considerations

Root motion in blend trees can produce weird averaged motion. If your “idle” clip has tiny root motion drift (common from mocap), blending idle with walk at 10% walk produces a character that slowly drifts when “idle.” Fix by ensuring idle clips have Bake Into Pose on XZ checked — eliminates the drift.

“Root motion is animation authority. Either the animator owns position, or you do — not both without a plan.”

Related Issues

For animator state transition issues, see Mecanim Root Motion Sliding on Transition. For animation event timing, Animation Event Not Firing in Blend Tree covers related animator issues.

Apply Root Motion checked, Bake Into Pose off for XZ, OnAnimatorMove for CharacterController. That is the triangle.