How do I play an animation montage on a skeletal mesh component from c++ such that I can get callbacks for OnCompleted, OnBlendOut, OnInterrupted, etc… just like the “PlayMontage” node in the picture?
I found this function but I don’t see any way to bind callbacks to it:
You can look into the UPlayMOntageCallbackProxy how it’s done in the engine.
But what basically happens is,
The montage is started with AnimInstance->Montage_Play and if that is successful you set right callbacks on the animinstance:
Did you managed to bind it? I bound it without errors, however the bound function is never called when even though the AnimMontage is clearly playing nothing is logged:
(For the next people that get stuck here) I had the same problem and managed to fix it by adding UFUNCTION() infront of the PlayMontageNotifyEnd(FName NotifyName, const FBranchingPointNotifyPayload& BranchingPointNotifyPayload) in header file.
Though problem solved, for ones who want to implement a really complicated system with montage timing callbacks, I highly recommend you to use Ability System Component. Example here shows how a montage play tasks with such delegates is made:
Yoo Can you show me how you did it?
||
void UMCombatComponent::PlayChainedAttackMontage(UAnimMontage* MontageToPlay)
{
/* Play chained attack and set the character in air */
// Add delay before playing If needed
M_CharacterBase->PlayAnimMontage(MontageToPlay, 1.0f);
if (IsInAir()) SetMovementMode(EMovementMode::MOVE_Flying); // maybe remove it later
AttackIndex = -1;
if (IsInAir())
{
SetMovementMode(EMovementMode::MOVE_Falling);
}
//Mesh->GetAnimInstance()->OnPlayMontageNotifyBegin.RemoveDynamic(this, &UMCombatComponent::OnMontageNotifyBegin);
}
void UMCombatComponent::OnMontageEnded(UAnimMontage* Montage, bool bInterrupted)
{
/* this function checks if the montage completed playing or if it was interupted */
if (bInterrupted)
{
UE_LOG(M_CombatComponent, Display, TEXT(“Montage Interupped”));
if (AttackIndex == GetChainedCombo().ComboMax)
{
AttackIndex = -1;
if (IsInAir())
{
SetMovementMode(EMovementMode::MOVE_Falling);
}
}
}
else
{
UE_LOG(M_CombatComponent, Display, TEXT(“Montage Complete”));
AttackIndex = -1;
}
//Mesh->GetAnimInstance()->OnMontageEnded.RemoveDynamic(this, &UMCombatComponent::OnMontageEnded);
}
||
In BeginPlay