but when I run the PlayTwice() function it does not play the montage at all
I’m guessing maybe the Montage_Stop() actually runs after AddDynamic() maybe in the next tick frame?
How do I make it work as intended?
Note: I’ve intentionally binded to OnMontageEnded please do not recommend to remove it
From looking at the code, PlayTwice()should make it play once, on the second call of BeginMontage().
The current setup plays a montage but immediately stops playing since CurrentMontage was set by the last call of BeginMontage(), which calls EndMontage() (sorry if that was hard to follow haha)
If you want it to run twice I’d recommend making a queue of some sort, maybe an array, and when the montage ends EndMontage() checks for montages in the queue and plays if there are any. PlayTwice can call BeginMontage() then add the same montage to the queue.
As for the delegates and timings, I’d recommend stepping through using a debugger and seeing when your code runs and the delegate fires. If you can’t debug for whatever reason I’d be happy to try in a bit.
I looked through the source a bit and this is what I assume is happening:
Either by calling Montage_Stop() or playing another montage, the current montage (if it exists) is stopped
Montage_Stop() takes a float to determine how long the montage has to blend out
When a montage is stopped, you specify 0.0f as the blend out time
When a montage is overridden (another is played when montage is playing) it uses the current montage’s blend in time
This blend out value is used in a timer/delay, then when this timer/delay is finished OnMontageEnded is broadcast. Since 0.0f is likely passed as the time of the delay, this means it will still take one tick to process the timer and then call OnMontageEnded.
Either that is the case, or no timer is created since the blend out time is <=0.0f, however processing the ended montage and broadcasting OnMontageEnded still carries over into the next tick.
Basically, to solve your problem:
Implement a queue system with an array. Upon a montage ending, check for montages in the queue and play them if there are any. This should fix it and play twice, as you aren’t overriding any animations and thus aren’t dealing with the AnimMontage broadcasting OnMontageEnded the tick after starting your montage.
This system would probably be better than using FTimerHandles as it waits for the montage to completely finish, accounting for play rates and everything in between.
Here is an example on how to implement it, without error checking:
(keep in mind I did not write this in an IDE so it may not directly compile, but should give you an idea on what to add)
No problem. Yes that would work perfectly fine, if you have one montage which I assume you do. I was thinking about multiple montages.
Glad you have solved it!