Blending Animations

Blending and Weighting Animations

Weights mix groups playing at once: group.weight (or an animatable's, or scene.beginWeightedAnimation) scales each contribution; the default -1 means unweighted, so set it on every group you mix. Blending eases from the current pose into a newly started animation (enableBlending, blendingSpeed), and additive groups (AnimationGroup.MakeAnimationAdditive) layer a gesture on top. Three foxes, weighted from Walk to Run as in Crossfading Actions, at 0.3 seconds:

Walk, an even blend of Walk and Run, and Run on three instantiated foxesHTMLLive
<canvas id="view" style="width: 620px; height: 140px"></canvas>
<script src="https://cdn.jsdelivr.net/npm/babylonjs@9.28.0/babylon.js"></script>
<script>
(async () => {
  const cdn = 'https://cdn.jsdelivr.net/npm/babylonjs-loaders@9.28.0/';
  await BABYLON.Tools.LoadScriptAsync(cdn + 'babylonjs.loaders.min.js');
  const engine = new BABYLON.Engine(view, true, {}, true);
  const scene = new BABYLON.Scene(engine);
  scene.clearColor = BABYLON.Color4.FromHexString('#eceff1ff');
  scene.createDefaultLight();
  const target = new BABYLON.Vector3(0, 0.22, 0);
  new BABYLON.ArcRotateCamera('side', -Math.PI / 2, 1.45, 1.25, target, scene).fov = 0.6;
  const container = await BABYLON.LoadAssetContainerAsync('fox.glb', scene);
  [1, 0.5, 0].forEach((walkWeight, i) => {
    const { rootNodes, animationGroups } = container.instantiateModelsToScene();
    const holder = new BABYLON.TransformNode(`fox${i}`, scene);   // scale and turn the copy
    rootNodes[0].parent = holder;
    holder.scaling.setAll(0.005);                                  // centimeters to meters
    holder.position.x = (i - 1) * 0.95;                            // side by side, side view
    holder.rotation.y = Math.PI / 2;
    const [, walk, run] = animationGroups;                         // Survey, Walk, Run
    walk.weight = walkWeight;
    run.weight = 1 - walkWeight;
    for (const group of [walk, run]) group.start(true).goToFrame(18, true).pause();
  });
  scene.executeWhenReady(() => engine.runRenderLoop(() => scene.render()));
  scene.onAfterRenderObservable.add(() => { window.__done = scene.getFrameId() > 5; });
})();
</script>
Walk, a 50/50 blend and Run at frame 18 (0.3 s). Fox model by PixelMannen (CC0), rigging and animation by tomkranis (CC BY 4.0), glTF conversion by @AsoboStudio and @scurest (CC BY 4.0), via the Khronos glTF Sample Assets
Walk, a 50/50 blend and Run at frame 18 (0.3 s). Fox model by PixelMannen (CC0), rigging and animation by tomkranis (CC BY 4.0), glTF conversion by @AsoboStudio and @scurest (CC BY 4.0), via the Khronos glTF Sample Assets

Seek with goToFrame(frame, true), or each group writes its full pose and the last wins. Moving the weights from Walk to Run over half a second is a crossfade; syncAllAnimationsWith() keeps the strides in step.