콘텐츠로 이동

UE5 Animation Notify 시스템

AnimNotify는 애니메이션 재생 중 특정 프레임에 이벤트를 발생시키는 시스템입니다.

  • AnimNotify: 단일 프레임에서 한 번 실행
  • AnimNotifyState: 시작~종료 구간 동안 지속 (Tick 포함)
FootstepNotify.h
UCLASS()
class UFootstepNotify : public UAnimNotify {
GENERATED_BODY()
public:
virtual void Notify(USkeletalMeshComponent* MeshComp,
UAnimSequenceBase* Animation,
const FAnimNotifyEventReference& EventReference) override;
UPROPERTY(EditAnywhere) USoundBase* FootstepSound;
UPROPERTY(EditAnywhere) FName SocketName = "foot_l";
};
// FootstepNotify.cpp
void UFootstepNotify::Notify(USkeletalMeshComponent* MeshComp, ...) {
if (!MeshComp || !FootstepSound) return;
FVector SocketLoc = MeshComp->GetSocketLocation(SocketName);
UGameplayStatics::PlaySoundAtLocation(MeshComp, FootstepSound, SocketLoc);
}

에디터에서 AnimSequence → Notifies 트랙에 추가하면 됩니다.

UCLASS()
class UDashTrailNotifyState : public UAnimNotifyState {
GENERATED_BODY()
public:
virtual void NotifyBegin(USkeletalMeshComponent* MeshComp,
UAnimSequenceBase* Animation, float TotalDuration,
const FAnimNotifyEventReference& EventReference) override;
virtual void NotifyTick(USkeletalMeshComponent* MeshComp,
UAnimSequenceBase* Animation, float FrameDeltaTime,
const FAnimNotifyEventReference& EventReference) override;
virtual void NotifyEnd(USkeletalMeshComponent* MeshComp,
UAnimSequenceBase* Animation,
const FAnimNotifyEventReference& EventReference) override;
};
void UDashTrailNotifyState::NotifyBegin(...) {
if (auto* Char = Cast<AMyCharacter>(MeshComp->GetOwner()))
Char->EnableDashTrail(true);
}
void UDashTrailNotifyState::NotifyEnd(...) {
if (auto* Char = Cast<AMyCharacter>(MeshComp->GetOwner()))
Char->EnableDashTrail(false);
}

Blueprint 이벤트 대신 C++ AnimInstance에서 직접 처리할 수 있습니다.

UCLASS()
class UMyAnimInstance : public UAnimInstance {
GENERATED_BODY()
public:
// 함수 이름이 "AnimNotify_{NotifyName}" 패턴이면 자동 바인딩
UFUNCTION()
void AnimNotify_AttackHit();
UFUNCTION()
void AnimNotify_DrawWeapon();
};
void UMyAnimInstance::AnimNotify_AttackHit() {
if (auto* Char = Cast<AMyCharacter>(TryGetPawnOwner()))
Char->GetWeapon()->EnableHitDetection(true);
}

AnimSequence의 Notify 이름과 함수 이름이 일치하면 자동으로 연결됩니다.

UCLASS()
class UHitboxNotify : public UAnimNotify {
GENERATED_BODY()
UPROPERTY(EditAnywhere) float DamageMultiplier = 1.0f;
UPROPERTY(EditAnywhere) EHitType HitType = EHitType::Light;
virtual void Notify(USkeletalMeshComponent* MeshComp, ...) override {
if (auto* Combat = MeshComp->GetOwner()->FindComponentByClass<UCombatComponent>())
Combat->BeginAttack(DamageMultiplier, HitType);
}
};
// Montage 재생 후 특정 Notify 이벤트 구독
void AMyCharacter::PlayAttackMontage() {
if (!AttackMontage) return;
FOnMontageNotifyBegin NotifyDelegate;
NotifyDelegate.BindLambda([this](FName NotifyName, const FBranchingPointNotifyPayload&) {
if (NotifyName == "AttackHit") OnAttackHit();
});
UAnimInstance* Anim = GetMesh()->GetAnimInstance();
Anim->OnPlayMontageNotifyBegin.Add(NotifyDelegate);
Anim->Montage_Play(AttackMontage);
}
  • UAnimNotify: 단일 프레임 이벤트 (발소리, 이펙트 스폰 등)
  • UAnimNotifyState: 구간 이벤트 (무기 히트박스 활성화, 트레일 등)
  • AnimInstance에 AnimNotify_{Name} 함수 정의하면 자동 바인딩
  • Notify에 UPROPERTY로 파라미터를 추가해 에디터에서 수치 조정 가능
  • Montage의 OnPlayMontageNotifyBegin으로 런타임 구독 가능