Grouping Animations
An AnimationGroup allows you to link together animations and meshes and play them, pause them, and stop them as a group.
Forming a Group
Follow the tutorial for creating an animation to set up one or more animations.
For example, having created animation1, animation2, and animation3, and also meshes mesh1, mesh2, mesh3, and mesh4, you can form the following animation groups
import { AnimationGroup } from "@babylonjs/core/Animations/animationGroup";const animationGroup1 = new AnimationGroup("Group1");const animationGroup2 = new AnimationGroup("Group2");and then use the addTargetedAnimation method to link the animations with the meshes and add them to the groups
animationGroup1.addTargetedAnimation(animation1, mesh1);animationGroup1.addTargetedAnimation(animation3, mesh1);animationGroup1.addTargetedAnimation(animation2, mesh2);
animationGroup2.addTargetedAnimation(animation2, mesh3);animationGroup2.addTargetedAnimation(animation1, mesh4);animationGroup2.addTargetedAnimation(animation2, mesh4);animationGroup2.addTargetedAnimation(animation3, mesh4);Because the animations may have been created with different timelines, they may need to be aligned using normalize
Normalize a Group
It may be that animation1, animation2 and animation3 have all been created using different numbers of frames. For instance animation1 may go from frame 0 to frame 80, animation2 from frame 0 to 75 and animation3 from frame 0 to frame 100. You can use the normalize method to make the number of frames the same for all animations, as in
animationGroup2.normalize(0, 100);In general the parameters for normalize are the numbers beginFrame and endFrame.
The beginFrame number must be less than or equal to the smallest begin frame of all animations, for the above examples not greater than 0.
The endFrame number must be greater than or equal to the largest end frame of all animations, for the above examples not less than 100.
Speed Ratio for the Group
The speedRatio for all animations in the group can be set, for example,
animationGroup1.speedRatio = 0.25;animationGroup2.speedRatio = 3;This speeds up or slows down the animation.
Creating a group from existing animatables
You can create a new AnimationGroup from an animatable by enumerating the animations contained in the animatable:
import { AnimationGroup } from "@babylonjs/core/Animations/animationGroup";const animationGroup = new AnimationGroup("my-animation-group");for (anim of idleAnim.getAnimations()) { animationGroup.addTargetedAnimation(anim.animation, anim.target);}Example: - Create AnimationGroup From Animatable
On Group Animation End
There is an onAnimationEnd observable that can be used to trigger a function when the animation ends.
animationGroup1.onAnimationEndObservable.add(function () { mesh2.material = redMaterial;});On Group Animation Loop
There is an onAnimationLoop observable that can be used to trigger a function when the animation loops.
animationGroup1.onAnimationLoopObservable.add(function (targetAnimation) { console.log(targetAnimation.animation.name);});There is also an onAnimationGroupLoop observable that can be used to trigger a function when all the animations in the group have looped:
animationGroup1.onAnimationGroupLoopObservable.add(function (group) { console.log("Group looped!");});Masking animations in a group
Masking allows you to define which animations should or should not be played.
By default (without mask), all animations added to an animation group will be played. If you wish only certain animations to be played, you can create an AnimationGroupMask:
import { AnimationGroupMask, AnimationGroupMaskMode } from "@babylonjs/core/Animations/animationGroupMask";const mask1 = new AnimationGroupMask([sphereA.name, sphereB.name], AnimationGroupMaskMode.Include); // play only animations affecting sphereA and sphereBanimGroup.mask = mask1;const mask2 = new AnimationGroupMask([sphereA.name, sphereB.name], AnimationGroupMaskMode.Exclude); // play all animations except those affecting sphereA or sphereBanimGroup.mask = mask2;You can use this Playground to test the mask property: Animation group mask
Note that if you use the same mask for the entire lifetime of an animation group, you can save performance and memory by removing from the animation group any animations that are rejected by the mask.
You can do this easily by calling the method AnimationGroup.removeUnmaskedAnimations().
What's more, if you update the mask while the animation group is already playing, you need to call the AnimationGroup.syncWithMask() method to ensure that the correct animations are stopped/played according to the new mask.
Ordering animation groups
The AnimationGroup.playOrder property defines the order in which animatables created at animation group startup should be processed in the list of active animatables.
This property can be useful when you want to ensure that certain animation groups / animatables are played before or after others (as in a layered system animation, for example).
By default, when playOrder is not set (it defaults to 0), animatables are played in the order in which they were created.
Miscellaneous
AnimationGroup.enableBlending, AnimationGroup.blendingSpeed and AnimationGroup.weight are helper properties that allow you to easily set these values for all animatables in the animation group at once, without having to go through the list of animatables yourself.