Problems with the reliability of AnimNotifyState::EndNotify.
(Expected behavior, but important to note: If you cancel/restart a montage during tick, a previous same frame notify will be delivered incorrectly or late, after the Montage End. Stting the notify to Branchpoint helps.)
Now the real bugs:
- When branching back to the same animation, all NotifyState guarantees are off
- Re-starting the same animation before another is finished, will screw up your notifies and their callbacks
- EVEN with Branchpoint=true, this is still true
- When canceling an ability montage with a regular montage, the ability montage entity may receive delegate callbacks that came from a different montage. This is because non-ability montages don’t increment the LocalAnimMontageInfo.PlayInstanceId.
For these reasons, I made these changes:
(Solution attempt 1)
-at first, created ReliableNotifyState with isNativeBranchingPoint=true -- THIS DID NOT FIX IT.
(Solution 2)
-created ReliableNotifyState, which is a global list of all NotifyStates that have been started. When a Montage Ended event is received, I ForceNotifyEnd on all notifies that match the Montage/Animatable key.
Solution 2 partially worked - unless I branch to the SAME montage. Example: the player taps melee, then waits for the branch window and cancels the tail of the melee by restarting it (branch back into restarting itself.)
So the problem here is that you just can’t tell the difference between notifies that were triggered from the 1st or 2nd melee. The notifyEnds don’t get flushed before the new montage is started (not even when using branchpoint) so it appears you never received the EndNotify from the previous montage.
(Solution 3) I exposed MontageEndedEvent.MontageInstanceID like so:
void UAnimInstance::TriggerMontageEndedEvent(const FQueuedMontageEndedEvent& MontageEndedEvent)
{
…
OnMontageEnded.Broadcast(MontageEndedEvent.Montage, MontageEndedEvent.bInterrupted, MontageEndedEvent.MontageInstanceID);
…
Now I can tell whether an EndNotify came from a previous montage play.
------------------
Question 1: The current documentation really glosses over this and makes it seem like this should all “just work”. Is there an alternate solution? Is this expected when branching back into the same montage and triggering montage stops from outside GAS? Maybe the documentation could include a little mention of these details.