Our animation system is using motion matching, and based on the 5.6 GASP project. We recently ran into an issue where under specific circumstances, the motion matching anim node would get the same search result from the Pose Search Database each update, with bJumpToPose set, resulting in it pushing that same pose to the blend stack each update.
The blend stack has this logic in FAnimNode_BlendStack_Standalone::InternalBlendTo:
// If we don't add a new player, re-use the same graph...
else if (!bBlendStackIsEmpty && AnimPlayers[0].GetBlendInPercentage() < 1.f &&
AnimPlayers[0].GetCurrentBlendInTime() < MaxBlendInTimeToOverrideAnimation)
{
// replacing AnimPlayers[0] with this new BlendTo request
UE_LOG(LogBlendStack, Verbose, TEXT("FAnimNode_BlendStack_Standalone '%s' replaced by '%s' because blend time in is less than MaxBlendInTimeToOverrideAnimation (%.2f / %.2f)"), *AnimPlayers[0].GetAnimationName(), *GetNameSafe(AnimationAsset), AnimPlayers[0].GetCurrentBlendInTime(), MaxBlendInTimeToOverrideAnimation);
}
The second if check in there is the problem. Provided MaxBlendInTimeToOverrideAnimation is > deltatime, then each update, the new blend request replaces the most recent one (index 0), and has its blend weight reset back to 0. Then it ticks once, before being replaced and reset again on the next update.
As a result of this, when the motion matching system picks the same pose each frame in this fashion, the character stays stuck in their original pose and will never blend in to the requested one.
This could be fixed by tweaking MaxBlendInTimeToOverrideAnimation, but this causes other problems, as there are situations where you would want to ignore or replace blends that were only ever requested once and then became irrelevant.
I was able to resolve the issue locally by adding a check in that if statement:
else if (!bBlendStackIsEmpty && (AnimPlayers.Num() == MaxActiveBlends) && AnimPlayers[0].GetBlendInPercentage() < 1.f &&
AnimPlayers[0].GetCurrentBlendInTime() < MaxBlendInTimeToOverrideAnimation)
however I don’t think this is the best solution. Perhaps we could instead check if the asset is the same as the one in index 0?
[Attachment Removed]