Click or drag to resize
DigitalRuneHow To: Blend Between Walk and Run Animation

This topic explains how to blend between a "Walk" and a "Run" animations based on the speed of a character.

This topic contains the following sections:

Method 1: Varying playback speeds and animation transitions

The character needs to have two animations: The "Walk" animation lets the character walk at average speed and the "Run" animation lets the character sprint with maximal speed. (Each animation contains a single walk cycle.)

C#
// Load the animations.
SkeletonKeyFrameAnimation walkAnimation = animations["Walk"];
SkeletonKeyFrameAnimation runAnimation = animations["Run"];

// Create an AnimationClip<T> to loop the animation.
var cyclicWalkAnimation = new AnimationClip<SkeletonPose>(walkAnimation)
{
  LoopBehavior = LoopBehavior.Cycle,
  Duration = TimeSpan.MaxValue,
};

var cyclicRunAnimation = new AnimationClip<SkeletonPose>(runAnimation)
{
  LoopBehavior = LoopBehavior.Cycle,
  Duration = TimeSpan.MaxValue,
};

When the character starts moving, start by playing the "Walk" animation.

C#
// Start "Walk" animation.
var animationController = AnimationService.StartAnimation(
  walkAnimation, 
  (IAnimatableProperty)_skeletonPose);
animationController.AutoRecycle();

Vary the playback speed of the animation to match the speed of the character.

C#
// Play walk animation at half speed:
animationController.Speed = 0.5f;

Once the speed exceeds a certain threshold, switch to the run animation using a short fade-in duration:

C#
animationController = AnimationService.StartAnimation(
  cyclicRunAnimation,
  (IAnimatableProperty)_skeletonPose,
  AnimationTransitions.Replace(0.2f));
animationController.AutoRecycle();

The problem with this approach is that the "Run" animation is not automatically synchronized with the "Walk" animation. The transition is acceptable in the most cases, but will create some animation glitches in the worst case (when the right foot is in front in the "Walk" animation, but the left foot is in front in the "Run" animation).

Method 2: Animation blending using a BlendGroup

The more accurate (but a bit more expensive way) way is to use a BlendGroup. A BlendGroup is an animation that blends cyclic animations with different length.

Load the animations as before, but instead of creating an AnimationClipT add the animations to a new BlendGroup.

C#
// Load the animations.
SkeletonKeyFrameAnimation walkAnimation = animations["Walk"];
SkeletonKeyFrameAnimation runAnimation = animations["Run"];

// Add the animations to a new blend group.
BlendGroup walkRunAnimation = new BlendGroup
{
  LoopBehavior = LoopBehavior.Cycle, 
  Duration = TimeSpan.MaxValue
};
walkRunAnimation.Add(walkAnimation);
walkRunAnimation.Add(runAnimation);
walkRunAnimation.SynchronizeDurations(); // Needs to be called once!
walkRunAnimation.SetWeight(0, 1.0f);     // Enable walk animation.
walkRunAnimation.SetWeight(1, 0.0f);     // Disable run animation.

The method SynchronizeDurations needs to be called once after all animations have been added.

The BlendGroup can be used like any other animation. For example, to start the animation call:

C#
AnimationService.StartAnimation(
  walkRunAnimation, 
  (IAnimatableProperty)_skeletonPose
  ).AutoRecycle();

The blend weights can be used to create a seamless transition from walking to running. (Note: The blend weights are automatically normalized.)

C#
// Cross-fade between "Walk" and "Run":
walkRunAnimation.SetWeight(0, 0.5f); // 50% walk
walkRunAnimation.SetWeight(1, 0.5f); // 50% run

BlendGroup are actually pretty powerful: A BlendGroup can blend any number of animations, not just two. For example, it is possible to mix a "Walk" animation with a "Run" animation and a "Limp" animation.