Quick answer: Transitions blend the root motion deltas of both states. If one clip bakes position into the animation and the other does not — or if blend tree speeds do not match clip speeds — Unity feeds your controller a mismatched velocity and the character glides. Make baking settings consistent and route deltas through OnAnimatorMove.
Here is how to fix Unity Mecanim root motion sliding on transition. Your idle looks fine. Your run looks fine. But the moment the Animator transitions from idle to run, or from run to stop, the character floats forward like it is on a conveyor belt. Sometimes it snaps back at the end of the transition. Sometimes it overshoots a waypoint. This is one of the oldest Mecanim pain points, and the fix is not a single setting — it is a consistent pipeline across clips, blend trees, and your movement code.
The Symptom
During a state transition — usually the 0.15 to 0.25 second blend window — the character’s root position drifts in a way that neither the source nor destination animation should produce. A common example is idle-to-run: the legs start pumping, but the torso is already sliding forward before a single foot has pushed off. Another common case is stop-to-idle: the feet plant, but the body continues to glide an extra 10–30 centimetres before settling.
If you draw animator.deltaPosition as a debug line every frame, you will see a spike during the transition window that does not match either clip’s isolated delta. That spike is the blended output of two root motion curves being mixed with a weight that does not match their natural timing.
What Causes This
Mecanim computes root motion by evaluating the root transform curve on every active state, weighting by the transition value, and summing. Three things commonly go wrong:
- Inconsistent bake settings. One clip has Bake Into Pose checked on Root Transform Position (XZ); the other does not. The blend combines baked-in displacement with live displacement, doubling or cancelling the delta.
- Blend tree speed mismatch. A run clip authored at 4 m/s is played at
Speed = 0.5to look like a jog. The visual speed halves, but root motion halves too — and the blend now produces motion at a rate the rest of your logic was not expecting. - IK pass ordering. If an IK pass runs before root motion is consumed, the IK foot target moves with the sliding root, producing feet that look correct but on a body that is gliding.
The Fix
Step 1: Audit your clip import settings. Select every clip that participates in a transition. In the Animation tab, compare Root Transform Position (XZ) and Root Transform Rotation. Bake Into Pose must be identical across all clips in the same blend. Pick one convention for your project — typically unbaked for locomotion, baked for idles and turns — and enforce it.
Step 2: Override OnAnimatorMove. Route the Animator delta through your controller so transitions, gravity, and collisions agree:
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class MecanimMotor : MonoBehaviour
{
private Animator animator;
private CharacterController cc;
private void Awake()
{
animator = GetComponent<Animator>();
cc = GetComponent<CharacterController>();
}
// Called by the Animator each frame after evaluation
private void OnAnimatorMove()
{
Vector3 delta = animator.deltaPosition;
// Snap to ground and add gravity; do not trust the clip for Y
delta.y = ComputeGravity() * Time.deltaTime;
cc.Move(delta);
transform.rotation *= animator.deltaRotation;
}
}
Step 3: Match blend tree speeds to clip speeds. Open the blend tree and set Speed on each motion to match how the clip was authored. If you need to globally scale locomotion, use the Animator’s top-level Speed Multiplier or an animation event — not per-motion speeds.
Step 4: Fix the IK pass ordering. In the Animator window, click the layer settings gear. Ensure IK Pass is enabled on the base locomotion layer, and implement OnAnimatorIK so it reads the post-motion pose, not a pre-motion one:
private void OnAnimatorIK(int layer)
{
float weight = animator.GetFloat("FootIKWeight");
animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, weight);
// Raycast from the post-animation foot position, not transform.position
Vector3 footPos = animator.GetIKPosition(AvatarIKGoal.LeftFoot);
if (Physics.Raycast(footPos + Vector3.up, Vector3.down, out RaycastHit hit, 2f))
{
animator.SetIKPosition(AvatarIKGoal.LeftFoot, hit.point);
}
}
Why This Works
Root motion in Mecanim is a pose delta, not a velocity. It only has meaning when applied to the transform that produced it, in the same frame. By consuming animator.deltaPosition inside OnAnimatorMove, you guarantee the delta is applied exactly once, through your controller, with your collision rules. Transitions still blend internally — but the blended result passes through a single choke point instead of fighting with the transform system.
Matching blend tree speed to clip speed preserves the proportionality between animation time and world displacement. When both sides of a transition move through time at the same real-world rate, the delta curves line up and the blend produces a believable interpolation instead of a spike.
“Ninety percent of Mecanim sliding bugs disappear the moment you pick one baking convention and audit every clip against it.”
Related Issues
If transitions feel correct but your character’s feet still clip through the floor during turns, see Fix: Unity IK Constraint Snap on Animation Start for IK weight ramping strategies.
If the sliding only appears in builds and not the editor, your shader keywords may be stripped — see Fix: Unity Shader Keywords Stripped From Build.
One bake convention. One delta pipeline. No sliding.