"Foot-sliding on locomotion — pace clips by their authored stride, not the controller's top speed"
A character's feet slide across the ground during walk or run animations. The faster the character moves, the worse it looks — feet either moonwalk backward or skate forward without matching the ground speed.
The animation's PlaybackRate is set proportional to the controller's top-speed dial (e.g. MaxSpeed) instead of the clip's own authored ground distance per loop. A walk clip authored at 24 frames / 30 fps (0.8 s loop) covers a specific stride distance — that's baked into the keyframes and can't be changed at runtime. If PlaybackRate doesn't match actual movement speed to that depicted speed, the feet and the ground disagree.
Calculate the clip's depicted metres-per-second from its authoring, then set PlaybackRate as a ratio:
// Each clip has its own constant — measure from the authored stride
const float WalkClipMps = 1.125f; // 24f @30fps, ~0.9m stride
const float RunClipMps = 4.2f;
float depictedMps = isRunning ? RunClipMps : WalkClipMps;
anim.PlaybackRate = actualSpeed / depictedMps;Key details:
- Keep depicted-mps as its own constant per clip. Do not reuse the movement controller's top-speed value — they are independent.
- Write
PlaybackRateunconditionally every frame in your sequencer. This way a hard gait switch (walk to run) can never leave a stale rate from the outgoing clip. - Measure the stride from your DCC tool: export the root motion distance over one loop, divide by loop duration.
PlaybackRate = actualSpeed / depictedSpeed keeps the animation's foot-contact frames synchronized with the character's real ground displacement. At actualSpeed == depictedSpeed, the rate is 1.0 and the animation plays as authored. At half speed, the rate halves and the feet move half as fast — matching the ground exactly. Zero foot-slide at any speed.