考点: 动画事件系统、Notify 使用场景、自定义 Notify
参考答案:
- AnimNotify:动画时间轴上的"瞬时事件",在特定时间点触发一次,适用音效、粒子、伤害判定。
- AnimNotifyState:"持续区间事件",有开始/结束时间,支持 Tick 每帧更新,适用拖尾特效、碰撞检测区间、材质变化。
- C++ 自定义 AnimNotify:
UCLASS()
class UAnimNotify_PlaySound : public UAnimNotify
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sound")
USoundBase* SoundToPlay;
virtual FString GetNotifyName_Implementation() const override { return FString("PlaySound"); }
virtual void Notify(USkeletalMeshComponent* MeshComp,
UAnimSequenceBase* Animation,
const FAnimNotifyEventReference& EventReference) override
{
if (SoundToPlay && MeshComp)
{
UGameplayStatics::PlaySoundAtLocation(MeshComp->GetWorld(),
SoundToPlay, MeshComp->GetComponentLocation(), 1.0f, 1.0f);
}
}
};
- C++ 自定义 AnimNotifyState(重写 NotifyBegin / NotifyTick / NotifyEnd):
UCLASS()
class UAnimNotifyState_WeaponTrail : 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
{
}
};
- 对比总结:
| 特性 |
AnimNotify |
AnimNotifyState |
| 触发方式 |
单次瞬时 |
区间(Begin/Tick/End) |
| Tick 支持 |
无 |
有 |
| 适用场景 |
音效、粒子、伤害判定 |
拖尾、持续碰撞、材质变化 |
| 性能 |
更轻量 |
有 Tick 开销 |
易错点: "只在特定帧造成伤害"应使用 AnimNotifyState 定义碰撞检测区间,在 Tick 中检测碰撞,而非单个 Notify。
延伸: AnimNotify_PlayParticleEffect / AnimNotify_PlaySound 内置通知、蓝图自定义 Notify(覆盖 ReceiveNotify)、Notify 的网络同步考虑。