Pausing weighted animations on the last frame

Hi, I’m having trouble understanding how weighted animations work in Babylon… What I need is to pause an animation on the last frame once it has played, while the last frame still affects the model based on it’s weight. Here’s a playground showing an example: https://playground.babylonjs.com/#M2J61R#14

In the playground, when you press Jump it should stay on the last frame of the jump animation until the avatar hits the floor again. Currently it just resets to a T-pose instead…

Some things I’ve tried:

  • Setting disposeOnEnd = false on all the Animatables in the AnimationGroup … this causes a mess once the animation ends, with some strange results
  • Calling pause() and goToFrame(animation.to) when onAnimationGroupEndObservable is fired … this seems to do nothing at all
  • Setting all other animation weights to 0 while the animation is playing … this does appear to work, but is a false positive… Seems like what’s actually happening is that the model is simply no longer being manipulated during that time, which is an issue since our app applies a lot of subtle animations even during these “override animations” so there is always an animation with weight > 0 at some point…

It would also be nice to understand how exactly the weights are applied… What happens if two animations with weight 1 are running, do they actually end up as 0.5 each? Also, since I’m cloning the animations, is it safe to dispose() them until they play again or should all animations be kept “active” until they’re played again?

Any help would be appreciated, thanks…

So, I played around with it as well, and tried looping the last frame:

Animation Blending Tester | Babylon.js Playground (babylonjs.com)

But I am sure @Deltakosh will be able to provide a much better answer than this when he is available later.

1 Like

Thanks, though I guess this counts as #3 above (setting all weights to 0, or in this case not playing any other animations)…

I would need a far simpler repro case, they are thousands of unnecessary things in this playground.
We have code running on a per frame basis to update walk or look and I believe this has nothing to do with the problem :slight_smile:

some hints:

  • if you want to blend two animations, they must have the same length or else the shortest will be dispose at the end. I see that you tried to not dispose it at the end and that was a good instinct. the best is to make sure the animation last until you don’t need it by adding an additional key at the end (same value but frame set where you need it)
  • Blending animation is actually dumb :slight_smile: it takes the value computed from animA x factorA and add it to animB x factorB. So if factorA is 1 and factorB is 1 then you simply add them :slight_smile:
1 Like

Thanks :+1: … For now I think I’ve gotten it working with a combination of disposeOnEnd = false, manually looping them on the last frame at the end of the animation, and never actually ever disposing animations, just setting their weights to 0 when they end (so restarting the same animation again when it needs to be played again)…

Would be nice if there was an equivalent of Three.js’s clampWhenFinished property :slight_smile:

1 Like