今天要做的是,在執行攻擊動畫時,增加傷害判定 (Collision)。
Animation
資料夾 (或你習慣的整理方式)iThomeAnimNotifyState_DoAttackTrace.h
跟 .cpp
Notify 跟 NotifyState 差在前者只能判斷
進入
notify 的時候,後者可以判斷開始 過程 結束
iThomeAnimNotifyState_DoAttackTrace.h
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimNotifies/AnimNotifyState.h"
#include "iThomeAnimNotifyState_DoAttackTrace.generated.h"
UCLASS()
class UiThomeAnimNotifyState_DoAttackTrace : public UAnimNotifyState
{
GENERATED_BODY()
protected:
// Trace 開頭 - 骨頭/Socket 名稱
UPROPERTY(EditAnywhere, Category="Attack")
FName TraceSocketStart;
// Trace 結尾 - 骨頭/Socket 名稱
UPROPERTY(EditAnywhere, Category="Attack")
FName TraceSocketEnd;
// Trace 半徑
UPROPERTY(EditAnywhere, Category="Attack")
float Radius=20.0f;
// Trace 類別
UPROPERTY(EditAnywhere, Category="Attack")
TArray<TEnumAsByte<EObjectTypeQuery>> CollideObjectType;
public:
// 在 Notify State 範圍內每禎觸發
virtual void NotifyTick(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float FrameDeltaTime, const FAnimNotifyEventReference& EventReference) override;
// Get the notify name
virtual FString GetNotifyName_Implementation() const override;
};
iThomeAnimNotifyState_DoAttackTrace.cpp
#include "iThomeAnimNotifyState_DoAttackTrace.h"
#include "Components/SkeletalMeshComponent.h"
#include "iThome30daysCharacter.h"
void UiThomeAnimNotifyState_DoAttackTrace::NotifyTick(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float FrameDeltaTime, const FAnimNotifyEventReference& EventReference)
{
// 試著呼叫使用這 NotifyState 的人(?) 的 DoAttackTrace 功能
if (AiThome30daysCharacter* Character = Cast<AiThome30daysCharacter>(MeshComp->GetOwner()))
{
Character->DoAttackTrace(TraceSocketStart, TraceSocketEnd, Radius, CollideObjectType);
}
}
FString UiThomeAnimNotifyState_DoAttackTrace::GetNotifyName_Implementation() const
{
return FString("Do Attack Trace");
}
iThome30daysCharacter.h
public:
virtual void DoAttackTrace(FName TraceSocketStart, FName TraceSocketEnd, float Radius, TArray<TEnumAsByte<EObjectTypeQuery>> CollideObjectType);
iThome30daysCharacter.cpp
void AiThome30daysCharacter::DoAttackTrace(FName TraceSocketStart, FName TraceSocketEnd, float Radius, TArray<TEnumAsByte<EObjectTypeQuery>> CollideObjectType)
{
GEngine->AddOnScreenDebugMessage((uint64)GetTypeHash(FString("wada")), 1, FColor::Orange, TraceSocketStart.ToString());
AActor* HitActor;
// 取得 Socket 的位置
const FVector Start = GetMesh()->GetSocketLocation(TraceSocketStart);
const FVector End = (TraceSocketEnd!=NAME_None) ? GetMesh()->GetSocketLocation(TraceSocketEnd) : Start;
TArray<AActor*> IgnoreActors;
IgnoreActors.Add(this);
FHitResult HitResult;
bool bHit = UKismetSystemLibrary::SphereTraceSingleForObjects(
this,
Start,
End,
Radius,
CollideObjectType,
false,
IgnoreActors,
EDrawDebugTrace::ForDuration,
HitResult,
true,
FColor::Red,
FColor::Green,
1.0f
);
if (bHit)
{
HitActor = HitResult.GetActor();
GEngine->AddOnScreenDebugMessage((uint64)GetTypeHash(FString("atkhit12312")), 1, FColor::Red, UKismetSystemLibrary::GetDisplayName(HitActor));
}
}
在 Animation Montage 新增一個 Track,右鍵 > Add Notify State > 剛剛的那個
修改參數
然後就完成了!
這裡用了2個 Socket 是為了之後可以用在武器上像是棍棒、劍之類的
這個。。做完之後覺得這個動畫 Notify 用藍圖做就好了,C++ 的 API 實在是太難找了,效率不會差太多,官網也寫不完全 = = ;
明天就可以讓他裝備武器了!