영상처럼 플레이어가 AI의 시야범위에 들어가면 AI는 캐릭터를 추격함
하지만 잘 추격하다가도 어느 순간 추격을 멈추는 상황이 발생하는 문제가 생겼음

하지만, AI가 이동을 멈춘 상태에서도 여전히 Chasing State를 유지하는 것이 확인되었음
현재 Move To Target State의 Task도 문제 없는 것 같아 State의 문제는 아니다고 판단하여 Rewind Debugger로 다른 부분도 확인해봄

AI의 이동이 멈추는 순간부터, Debugger의 Navigation부분에서 변동이 생기는 것을 확인
Navigation에 문제가 있을 것 같다고 생각하여 AI의 NavMesh를 확인하였음

추측대로, Chasing State는 유지되나 NavMesh가 끊겨 있어 이동이 불가능했던 것
레벨에서 NavMesh의 크기를 확장시켜 문제를 해결하였음


#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "ActivateInterface.generated.h"
UINTERFACE(MinimalAPI)
class UActivateInterface : public UInterface
{
GENERATED_BODY() // 여기는 내버려둠
};
class TARCOPY_API IActivateInterface
{
GENERATED_BODY()
public:
virtual void Activate(AActor* InInstigator) = 0; // 순수가상함수
};
IActivateInterface 여기에만 추가 구현// MyChest.h
class AMyChest : public AActor, public IInteractable
{
GENERATED_BODY()
public:
// 오버라이드 시 _Implementation을 붙입니다.
virtual void Activate_Implementation(AActor* InInstigator) override;
};
// MyChest.cpp
void AMyChest::Activate_Implementation(AActor* InInstigator) {
UE_LOG(LogTemp, Log, TEXT("Activated by %s"), *InInstigator->GetName());
}
부모로 인터페이스 추가
구현 시, _Implementation 붙여 사용
if (OtherActor->GetClass()->ImplementsInterface(UMyInterface::StaticClass()))
{
IMyInterface::Execute_Activate(OtherActor, this);
}
UObject 시스템을 이용해, 인터페이스를 가지고 있는 객체인지 먼저 확인
그리고 Execute_함수명으로 실행. 매개인자(Instigator)는 뒤에 넣어주면 된다
블루프린트와의 호환성을 위해 위와같이 작성하고, C++에서만 인터페이스 사용하면 다음과 같이 작성
// MyInterface.h
class IMyInterface
{
GENERATED_BODY()
public:
// UFUNCTION()을 붙이지 않고, 순수 가상 함수로 선언
virtual void Activate(AActor* InInstigator) = 0;
};
// MyActor.h
#include "MyInterface.h"
class MYPROJECT_API AMyActor : public AActor, public IMyInterface
{
GENERATED_BODY()
public
// _Implementation 없이 그냥 구현
virtual void Activate(AActor* InInstigator) override;
};
// MyActor.cpp
void AMyActor::Activate(AActor* InInstigator)
{
UE_LOG(LogTemp, Warning, TEXT("Activate"));
}
// 호출부
// 인터페이스로 업캐스팅
IMyInterface* InterfaceTarget = Cast<IMyInterface>(OtherActor);
if (InterfaceTarget)
{
// 직접 호출 (가장 빠르고 간결함)
InterfaceTarget->Activate(this);
}
T* 변수명 = Cast<T>(변수)
const가 붙은 변수를 변환할 때는 const T*로 해줘야함
보통 UObject의 포인터 변환에 사용
UObject가 아닐 땐 static_cast사용if (DamageEvent.IsOfType(FPointDamageEvent::ClassID))
{
const FPointDamageEvent& D = static_cast<const FPointDamageEvent&>(DamageEvent);
}
IsOfType처럼 캐스팅 가능한지 먼저 판단해주기
static_cast로 변환하기
dynamic_cast는 RTTI 오버헤드가 커서 사용추천 안 함