Model Engine 4 adds a new animation system that, to put it simply, is a direct upgrade from the previous Priority System. Hence, it was given a clunky yet precise name: Priority State-Machine Animation System.
Although the old system is still usable, we highly recommend switching over to using this new system as it can do everything the old system does but better and more flexible!
This bakes the question: What was wrong with the old system? A lot, apparently.
The Problem
Let's do a recap on the old system.
The Priority System relies on 2 very important assumptions:
- That each animation has a distinct priority and will never change
- That interpolating between two animations equates to fading in and out the animations, and adding them together
These assumptions are obviously very wrong. While the first point can be worked around, the second point affects
animation freedom severely, especially on interpolating rotations between two animations. Whenever you see weird
interpolation bugs happening when a model switches between IDLE
and WALK
state, that is the doing of the second
assumption.
To understand this problem a little bit better (for academic reasons,) here is a very simple example. If you don't care about it, first why are you here ?_?, second you can skip to the next part.
Let's say we have a model with an idle
and walk
animation, and let's compress the animations down to interpolating
between two values.
Animation | Value |
---|---|
default | 1 |
idle | 0 |
walk | 0 |
Let's visualize idle
trying to interpolate into walk
. Since both animations have the same value 0
, logically
speaking, the value would remain at 0. However, because we assumed that all animations have a defined priority, walk
is technically higher priority than idle
. Furthermore, we also assumed that interpolation is just adding two faded
values, our formula becomes: lerp(idle, default, progress) + lerp(default, walk, progress)
. Substituting progress
with 0.5
, we get lerp(0, 1, 0.5) + lerp(1, 0, 0.5)
, or 0.5 + 0.5 = 1
. Our interpolation somehow reached 1
.
The astute among you will realize that the culprit comes from the default model value being 1
, because if we set
default to 0
while the two animations to 1
, the formula works out. In fact, the formula functions properly as long
as the default value is 0
. This explains why simple models seldom encounter this, while more complex models that
requires default rotations suffers
greatly.
The Solution
Don't give animations a priority.
Yep, that's it. At least we are not using animation priorities for interpolations. The new system uses state-machines to ensure that only one animation is playing at a time, and interpolate animations directly from each other instead of doing through the default pose first.
However, since the state-machine can only play one animation, this means that animation overlapping is no longer available: a trait that the priority system allows. This is where we merge the two ideas into one.
Instead of one state-machine per model, each model can have an infinite amount of state-machines, all still limited to playing only one animation. We then assign priorities to these state-machines, so that the final result of the animation is computed with the values calculated by the state-machines.
Conclusion
I am a fucking genius.
To be fair it took me this long to figure this out, I'm ashamed of thinking the old system is a good idea. But it's
fixed now so woohoo!