언리얼 C++ 게임 개발의 정석/11. AI 컨트롤러와 비헤어비어 트리
11.1 AI Controller 와 내비게이션 시스템
ftftgop3
2024. 4. 29. 20:31
NPC : 레벨에 배치돼 스스로 행동 하는 캐릭터
AI Controller : NPC 들에 빙의 해 행동을 제어하는 클래스
ABAIController 생성 및 설정
AIController 를 상속 받은ABAIController 클래스 생성
ABCharacter 에서 ABAIController 사용 할 수 있게 지정 및 생성 옵션 설정
캐릭터가 생성 될 때 마다 ABAIController 가 생성 되고 캐릭터를 조종
#include "ABAIController.h"
AABCharacter::AABCharacter()
{
AIControllerClass = AABAIController::StaticClass();
AutoPossessAI = EAutoPossessAI::PlacedInWorldOrSpawned;
}
AIController 플레이어 추격 기능 추가
내비게이션 메시 기반의 길 찾기 시스템 구축
1. 내비게이션 메시 배치
모드 ▶불륨 탭 ▶ NavMesh Bounds Volume 드래그해 원점 배치
언리얼 뷰포트에서 P 입력 시 내비게이션 영역 확인
2. NPC 스스로 동작 기능
목적지를 알려주고 스스로 움직이도록 명령
3초마다 폰에게 목적지로 이동 하는 명령 제작
ABAIController
UCLASS()
class ARENABATTLE_API AABAIController : public AAIController
{
GENERATED_BODY()
public:
AABAIController();
//AI Controller 가 액터에 빙의
virtual void Possess(APawn* InPawn) override;
virtual void UnPossess() override;
private:
//타이머 설정
void OnRepeatTimer();
FTimerHandle RepeatTimerHandle;
float RepeatInterval;
};
#include "ABAIController.h"
AABAIController::AABAIController()
{
RepeatInterval = 3.0f;
}
void AABAIController::Possess(APawn* InPawn)
{
Super::Possess(InPawn);
//특정 시간마다 함수를 반복 실행
//RepeatTimerHandle 타이머 핸들로 RepeatInterval 초 마다 OnRepeatTimer() 실행, 반복 실행
GetWorld()->GetTimerManager().SetTimer(RepeatTimerHandle, this, &AABAIController::OnRepeatTimer, RepeatInterval, true);
}
void AABAIController::UnPossess()
{
Super::UnPossess();
//빙의 해제 시 타이머 초기화
GetWorld()->GetTimerManager().ClearTimer(RepeatTimerHandle);
}
void AABAIController::OnRepeatTimer()
{
//현재 빙의 된 폰 참조
auto CurrentPawn = GetPawn();
ABCHECK(CurrentPawn != nullptr)
//네비게이션 시스템 참조
UNavigationSystem* NavSystem = UNavigationSystem::GetNavigationSystem(GetWorld());
if (NavSystem == nullptr)
return;
FNavLocation NextLocation;
//네비게이션 시스템에서 이동 가능한 목적지를 랜덤으로 얻어 온다
if (NavSystem->GetRandomPointInNavigableRadius(FVector::ZeroVector, 500.0f, NextLocation))
{
//목적지로 폰이동
UNavigationSystem::SimpleMoveToLocation(this, NextLocation.Location);
ABLOG(Warning, TEXT("Next Location : %s "), *NextLocation.Location.ToString());
}
}