Issue Type: Other Impact: High Frequency: Constantly Date First Experienced: 2021-02-24 13:02:00 (-05:00) Date Last Experienced:
Reproduction Steps:
Have two animations set for the same priority. One should be looped, the other should not be looped.
Play the looped animation.
While the looped animation is being played, play the non-looped animation. This will cause the keyframes to stack together. The resulting animation is very off.
Expected Behavior:
The engine should properly handle multiple animations playing at once and not stack keyframes.
Here’s a repro containing a stripped down version of the gun. It only works in R6. Animations in dummy are included. Animation_Bug_Repro.rbxl (136.7 KB)
I’m looking at your repro place, and I can’t find the animation in the Dummy that has the vertical recoil we see in your video clips; “Fire” appears to only animate the slide? I just want to be sure I’m looking at the exact animations needed to reproduce the issue, thanks.
Is it intentional that you are playing the animations at the same priority? Normally, when you want an action to override an idle temporarily, it’s done by playing an animation over the idle at a higher priority. Tracks of the same priority are meant to do a weighted blend.
One of the bugs that the flag enabled this morning is meant to fix is the behavior when same-priority tracks are played and sum to a weight greater than 1.0. Without the flag, one of the tracks “wins” and cancels the other, but it’s sensitive to load order and difficult for the developer to control. It causes a situation where things work great in Studio, but in a live game the wrong animation plays for some players, because of the order the animation data finished loading for them from the CDN. With this bug fixed, the expectation is that 2 or more AnimationTracks of the same priority will do a consistent and reproducible weighted blend. But that means that any game that relies of the bug to stop one animation playing while another plays temporarily, will break. These games will need to make sure that the overriding animation either has a higher priority than the idle, or the AnimationTrack weights are being correctly set in a script to sum as intended. You can see an example of this in the avatar’s Animate LocalScript, walk and run animation tracks are blended, but are always forced to sum to 1.0
So the recoil you see in the videos above is done via springs offsetting both shoulders’ C0 properties. I removed it in the repro because the bug occurs without it, however if you need the full copy I can PM you it.
The tracks being set to the same priority level was done intentionally to ensure that they would not be interfered with by any lower priority animations that could occur with them at the same time.
As for the tracks “winning out on each other”, that is in a way what was being done, however before it appeared that the load order did not matter. All animation tracks are loaded into the humanoid when the tool is equipped, and then when a specific animation needs to play, the act of playing it prioritized it. I tested this thoroughly with a full server of around 60 players and none had issues with it. Now since the animations are blended together, they are playing “on top of each other.” While I realize this was the intention, I did not see any issue with the way it worked before, and now many games which relied on this behavior are broken. I will adjust the idle animation priority to fix the issue, but I feel like this new logic may not be obvious to new developers.
Yes, and the troubling thing about this is that there is no code in the engine that does what you’re suggesting–gives some implicit priority to the most-recently-played track. Play() and LoadAnimation() call order appearing to provide developer control over which animation track dominates is just because of how the system happens to manage and iterate over the currently-playing tracks. But this what software engineers refer to as reliance on implementation-defined behavior. In other words, it works now, but only coincidentally, not because of an ordering that is actually guaranteed by an API contract. Using Enum.AnimationPriority is the only means by which we guarantee that one track will override the influence of another. No other tricks of code or load ordering are future proof.
While the flag for this fix is currently off while we look into some issues with translation blending, the fixes we make have to prioritize enforcing the guarantees made by the API, and animations that broke due to reliance on evaluation ordering are not guaranteed to continue working. I definitely recommend republishing your firing animations with a higher priority than what you’re using for the idle arm pose, like you propose. This is the only way to guarantee the animations will override in the order you expect once this flag is turned back on.