Download

GAS, PlayMontageAndWait not calling "OnInterrupt"

Good day.

I’m using Gameplay Ability System and as far as I can tell, node “PlayMontageAndWait” by desing supposed to ends either by “OnCompleted” or “OnInterrupted” callbacks, no third option available.
But weird thing happened from time to time: there is a third option, which brake my gameplay logic, since I cannot distinguish this third case as any the first two.

From my analysis I conclude that this third case is “Interrupting PlayMontageAndWait1 by other PlayMontageAndWait2, called between Montage1 starts blendout, but before it’s ended”. This way PlayMontageAndWait1 calls only “OnBlendOut”, but not “OnCompleted” or “OnInterrupted”.
As I can see, the root of the problem is that in Engine/Source/Runtime/Engine/Private/Animation/AnimMontage.cpp, function FAnimMontageInstance::Stop() sends FQueuedMontageBlendingOutEvent only once per montage, so if blendout(interrupt==false) was called first, blendout(interrupt==true) will never be send.

Currently I’m planning to fix this behavior by letting montages send blendout(interrupt==true)-event even if Stop() was already called. Particularly by adding next code in the “else” branch of the Stop() function:

	if (Montage && bInterrupted)
	{
		if (UAnimInstance* Inst = AnimInstance.Get())
		{
		    Inst->QueueMontageBlendingOutEvent(FQueuedMontageBlendingOutEvent(Montage, bInterrupted, OnMontageBlendingOutStarted));
		}
	}

So, my questions are:

  • Whether I’m understand design behind PlayMontageAndWait() correctly and this is really a bug or I’m misunderstand something and this can\should be workarounded on higher level?
  • While proposed fix did fix problem I’m encountered, I’m wonder if there are some unforeseen consequences of such approach that I’m missed? Or is there a better way to fix it?

note: Actually i’m using custom “PlayMontageAndWaitForEvent” node, which I took from some example, but as far as I can see, part responsible for this problem is absolutely same in both nodes

Thanks in advance.