[UE5] FAnimNotifyEventReferenceから取得できる情報について(C++)

# はじめに

[アニメーション通知](https://dev.epicgames.com/documentation/ja-jp/unreal-engine/animation-notifies-in-unreal-engine?application_version=5.3)

UE5あたりから追加されている引数
`const FAnimNotifyEventReference& EventReference` 

から取得できる情報について
まとめたメモです。

```
// UAnimNotify
ENGINE_API virtual void Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, const FAnimNotifyEventReference& EventReference);

// UAnimNotifyState
ENGINE_API virtual void NotifyBegin(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference);
ENGINE_API virtual void NotifyTick(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, float FrameDeltaTime, const FAnimNotifyEventReference& EventReference);
ENGINE_API virtual void NotifyEnd(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, const FAnimNotifyEventReference& EventReference);
```




# 環境
UE5.4.1

# 基本情報の取得
```
// Notify情報（NotifyClassやDurationなど）
const FAnimNotifyEvent* NotifyEvent = EventReference.GetNotify();

// 通知元のアニメーションアセット（AnimSequenceやAnimMontageなど）
const UAnimSequenceBase* AnimSequenceBase = Cast<UAnimSequenceBase>(EventReference.GetSourceObject());
 
// Notifyが終了に達したか（キャンセルされなかったか）
bool bReachedEnd = UAnimNotifyLibrary::NotifyStateReachedEnd(EventReference);

// Notifyが発行されたアニメーションの時間を取得
float CurrentAnimationTime = UAnimNotifyLibrary::GetCurrentAnimationTime(EventReference);

// Notifyが発行されたアニメーションの比率(0-1)を取得
float CurrentAnimationTimeRatio = UAnimNotifyLibrary::GetCurrentAnimationTimeRatio(EventReference);

// NotifyStateの区間に正規化されたアニメーションの時間を取得
float CurrentAnimationNotifyStateTime = UAnimNotifyLibrary::GetCurrentAnimationNotifyStateTime(EventReference);

// NotifyStateの区間に正規化されたアニメーションの比率(0-1)を取得
float CurrentAnimationNotifyStateTimeRatio = UAnimNotifyLibrary::GetCurrentAnimationNotifyStateTimeRatio(EventReference)

```

# Montage関連
※UE5.3では下記方法では取得できなかったが、
　UE5.4からアクセス可能に修正された模様。
```
if (auto&& InstanceContext = EventReference.GetContextData<UE::Anim::FAnimNotifyMontageInstanceContext>())
{
	// MontageInstanceIDを取得
	int32 MontageInstanceID = InstanceContext->MontageInstanceID;
	
	// MontageInstanceIDからFAnimMontageInstanceを取得
	const FAnimMontageInstance* MontageInstance = AnimInstance->GetMontageInstanceForID(MontageInstanceID);
}
```

# ミラーリング関連
ミラーノードを使用している場合に通知される。
```
// ミラーリングされているか
bool bMirrored = UAnimNotifyMirrorInspectionLibrary::IsTriggeredByMirroredAnimation(EventReference);

// ミラーテーブルを取得（bMirrored=trueの時のみ）
const UMirrorDataTable* MirrorTable = UAnimNotifyMirrorInspectionLibrary::GetMirrorDataTable(EventReference);
```

# ステートマシン関連
アニメーションBPのステートマシン名、ステート名を指定して
そのステートマシンから通知されたかどうかを判定できる。
```
// Notifyが指定されたステートマシンからトリガーされたかどうか
bool bIsTriggeredByStateMachine = UAnimNotifyStateMachineInspectionLibrary::IsTriggeredByStateMachine(EventReference, AnimInstance, StateMachineName);

// Notifyが指定されたステートマシンとステートからトリガーされたかどうか
bool bIsTriggeredByStateInStateMachine = UAnimNotifyStateMachineInspectionLibrary::IsTriggeredByStateInStateMachine(EventReference, AnimInstance, StateMachineName, StateName);

// Notifyが指定されたステートからトリガーされたかどうか
bool bIsTriggeredByState = UAnimNotifyStateMachineInspectionLibrary::IsTriggeredByState(EventReference, AnimInstance, StateName);
```

# おわりに

EventReference.GetContextData～関連は
UAnimNotifyXXXLibrary～ライブラリ経由で取得するのが無難かもしれません。
（ちょくちょくクラスや関数の外部公開範囲が変わっている為）

Mirror判定や、MontageInstanceIDは同じMontageを再生した時などに
インスタンス単位での判定をしたいときに使ったりします。