Description

In the Animation Montage Editor, NotifyEnd is unexpectedly called when a time marker is in the middle of an AnimNotifyState and the animation preview gets paused. Because the Animation Montage Editor does not fill AnimInstance->NotifyQueue when it is paused. As a result, any existing AnimNotifyState that was in effect at the last frame is considered finished.

This can be inconsistent behavior. The other editors, such as the Animation Sequence editor, do NOT call NotifyEnd in the same scenario. (The downside is that NotifyTick is always called, even when the animation preview is paused.)

If we let the Animation Montage editor behave the same as the other animation editor, the possible solution is to call HandleEvents() function from FAnimMontageInstance::Advance()  in AnimMontage.cpp even when bPlaying is false.

void FAnimMontageInstance::Advance(float DeltaTime, struct FRootMotionMovementParams* OutRootMotionParams, bool bBlendRootMotion)
{
    SCOPE_CYCLE_COUNTER(STAT_AnimMontageInstance_Advance);	FScopeCycleCounterUObject MontageScope(Montage);
    if (IsValid())
    {
        // with custom curves, we can't just filter by weight
        // also if you have custom curve with longer 0, you'll likely to pause montage during that blending time
        // I think that is a bug. It still should move, the weight might come back later.
        if (bPlaying)
        {
            // ... skip ...
        }
+       else
+       {
+           HandleEvents(Position, Position, nullptr);
+       }
     }
}

The customer who reported this issue confirms that it can be fixed by calling HandleEvents() in a case where bPlaying is false.

Steps to Reproduce
  1. Create a new project based on ThirdPerson template.
  2. To visualize an issue, create a new Blueprint class which inherits AnimNotifyState class and override Received_NotifyEnd function in order to output some string (such as "NotifyEnd is called.") via PrintString.
  3. Create a new Animation Montage and open it.
  4. Drag & drop an animation sequence to DefaultGroup.DefaultSlot
  5. Add your own AnimNotifyState (defined at step1.)
  6. Make the notification wider.
  7. Play animation and pause it while a time marker (animation position cursor) is within the notification.
  8. Confirm Received_NotifyEnd is called in the mid of the notification time duration.

[Image Removed]

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-197891 in the post.

1
Login to Vote

Unresolved
ComponentUE - Anim - Gameplay
Affects Versions5.25.3.1
Target Fix5.5
CreatedOct 13, 2023
UpdatedDec 18, 2023