목차
- 에너미 패트롤 시키기
1. 에너미 패트롤 시키기
에너미가 일정 위치를 지속적으로 순찰하는 기능을 만들어 보려고 한다.
패트롤 타겟을 여러개 만들고 이 타켓들을 순찰하게 하고 싶은데 그러기 위해서 이 타켓들을 배열에 담아서 보관해야 한다.
C++에서 이 작업을 해보자. 에너미 클래스에 변수를 선언할 것이다.
// 현재 순찰중인 타켓
UPROPERTY(EditInstanceOnly, Category = "AI Navigation")
AActor* PatrolTarget;
// 타켓 배열
UPROPERTY(EditInstanceOnly, Category = "AI Navigation")
TArray<AActor*> PatrolTargets;
PatrolTarget은 현재 에너미가 향하고 있는 목표이다. CombatTarget이 nullptr이 되면 이 타겟을 따라 이동하게 할 것이다.
PatrolTargets 배열은 순찰할 목표들을 담을 배열이다.
이제 이 타겟 배열에서 타겟을 뽑고 그쪽으로 이동하게 하게 구현해보자.
가장 먼저 BeginPlay() 함수에서 첫 타겟을 쫒아가게 할 것이다. 에너미를 움직이기 위해서는 AIController를 가져올 필요가 있고 그러기 위해서는 추가적인 모듈이 필요하다.
빌드파일에 AIModule을 포함해주자. 그 다음 헤더파일에 AIController를 저장할 변수를 선언해주자. C++에서는 AIController 맨 앞에 A가 한번더 붙는다.
UPROPERTY()
class AAIController* EnemyController;
그리고 BeginPlay() 함수에서 이를 할당하고 MoveTo 함수를 통해 에너미가 이동하는 것을 구현해보자.
void AEnemy::BeginPlay()
{
Super::BeginPlay();
if (HealthBarWidget)
{
HealthBarWidget->SetVisibility(false);
}
EnemyController = Cast<AAIController>(GetController());
if (EnemyController)
{
EnemyController->MoveTo()
}
}
MoveTo() 함수의 매개변수로는 어떤 값을 넣어주어야 할까?
언리얼 문서에서 나와있는 매개변수는 다음과 같다.
virtual FPathFollowingRequestResult MoveTo
(
const FAIMoveRequest & MoveRequest,
FNavPathSharedPtr * OutPath
)
MoveRequest 는 FAIMoveRequest 는타겟 액터나 도착지의 위치, 도착 후 행동, 경로지정 여부등의 정보를 가지고 있는 구조체라고 한다. 더 자세한 정보는 언리얼 문서에서 확인할 수 있다.
OutPath 는 경로 정보를 반환받기 위한 FNavPathSharedPtr 타입의 포인터로 주로 디버깅을 하기 위해 사용한다.
FAIMoveRequest 구조체 먼저 정의해보자.
FAIMoveRequest MoveRequest;
MoveRequest.SetGoalActor(PatrolTarget);
MoveRequest.SetAcceptanceRadius(15.f);
SetGoalActor() 로 목표인 액터를 정해주었고,
SetAcceptanceRadius() 에서 목표에 얼마나 가까이 접근하는지를 지정해주었다.
이제 OutPath 변수를 만들어주자.
FNavPathSharedPtr NavPath;
FNavPathSharedPtr는 이미 타입자체가 포인터로 지정되어있기 때문에 따로 * 연산자를 쓰지 않아도 된다고 한다. 이제 MoveTo() 함수에 매개변수들을 넣어주면 된다.
EnemyController->MoveTo(MoveRequest, &NavPath);
NavPath는 경로정보를 저장한다고 하였다. 이 변수로부터 정보를 받아와보자.
NavPath->GetPathPoints();
그런데 이렇게 하면 에러가 나는 것을 볼 수 있다. FNavPathSharedPtr, 정확히는 FNavigationPath의 타입을 알지 못한다. 헤더파일을 가져올 필요가 있다.
#include "Navigation/PathFollowingComponent.h"
위의 헤더파일을 가져오면 된다. 해당 헤더파일을 가져오면 FNavigationPath 타입뿐 아니라 FAIMoveRequest 타입정의도 함께 들어있어 오류를 해결할 수 있다.
TArray<FNavPathPoint>& PathPoints = NavPath->GetPathPoints();
이제 다음과 같이 하여 FNavPathPoint 배열을 만들고 이 지점들을 그려보자
TArray<FNavPathPoint>& PathPoints = NavPath->GetPathPoints();
for (const FNavPathPoint& Point : PathPoints)
{
const FVector& Location = Point.Location;
DrawDebugSphere(GetWorld(), Location, 12.f, 12.f, FColor::Green, false, 20.f);
}
이렇게 하면 이제 AI 이동하는 경로를 시작적으로 볼 수 있게 된다.
이제 컴파일하고 잘 되는지 확인해보자. 물론 패트롤 타겟을 설정하는 것을 잊으면 안된다.
에너미가 타겟으로 이동하는 것은 물론 이동할때 목표로 지정하는 경로를 볼 수 있다.
이렇게 해서 에너미를 목표까지 이동하게 하였다. 하지만 현재는 순찰이 아닌 단순 이동일뿐이다. 다음에는 순찰 기능을 구현해보려고 한다.
'게임프로그래밍 > 실습1' 카테고리의 다른 글
[언리얼 실습] 58. 패트롤 대기 시간 추가하기 (0) | 2024.11.05 |
---|---|
[언리얼 실습] 57. 에너미 실제로 패트롤 시키기 (0) | 2024.11.04 |
[언리얼 실습] 55. 블랜드스페이스를 통해 에너미의 속도에 따른 애니메이션 구현하기 (0) | 2024.11.04 |
[언리얼 실습] 54. 네비게이션 매시 만들기 (0) | 2024.11.04 |
[언리얼 실습] 53. 원할 때만 체력바가 보이게 하기 (0) | 2024.11.04 |