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.

upd: btw, we are fine with this change so far. No unexpected consequences were found in a year~

4 Likes

Still using this fix? Did you found another solution?
UPD Looks like needs to use OnBlendOut, because any time animation blending out it means it was interrupted by something

hi, yes, still using this fix on 5.3.1, it’s still works fine.

Looks like needs to use OnBlendOut

I don’t really get your question since i have no problems with this fix. But if you mean “you can subscribe to OnBlendOut and treat it as OnInterrupted instead of proposed fix”, then you can’t: unless you using zero-length blendouts on your montages (which likely wouldn’t looks nice), the BlendOut can mean any of OnCompleted or OnInterrupted, depending on whether montage was interrupted or is naturally nearing its end and starting the legal blendout.

2 Likes

Initially I thought I had the same issue - but there is a fix for it now;
there’s a boolean called “Allow interrupt After Blend Out”, when calling “PlayMontageAndWait”.

if set to true - you will get the interrupt after blend out, which is this case.
Honestly not sure why you would want that flag to be false.