내일배움캠프 ch.5로 AI를 배우게 되었다.
여태 프로젝트를 진행하면서 GameMode(Gameflow logic), Character, Animation 을 담당했었고 AI는 다루지 않아서 꼭 배우고 싶었는데 마침 수강할 수 있게 되어 기쁘다.
언리얼에서 AI를 구동하기 위해서는 삼총사가 필요하다.
AI Controller :
Behavior Tree
Blackboard
Navmesh Bound VolumeNavMeshBoundVolume은 AI의 이동 가능 영역을 정의 해주는 볼륨. 네브메시의 시각화 및 비시각화 옵션을 활용해서 정상 동작을 직접 검증/평가 할 수 있다.


🔥 NavMesh는 Scale이 아니라 Brush크기를 활용해 레벨 내 적용되는 지오메트리를 결정한다.
따라서 Location을 변경한다던지, Rotation이나 Scale값을 변경해서 AI가 갈 수 있는 곳과 갈 수 없는 곳을 엔진 아키텍쳐상 동적으로 설정할 수 없다. 그러나 Project Setting 에서 Navmesh의 Runtime Generation을 Dynamic을 설정함으로써 타의 오브젝트를 통해 AI의 이동영역을 통제할 순 있다.



🔥 Dynamic 설정을 이용해서 Navmesh안에 Engine에 있는 오브젝트가 들어갔을 때 Navmesh의 영역이 새로 확장되는 것을 볼 수 있다.




🔥 Dynamic 설정과는 다르게 Navmesh가 액터의 이동에 따라 없어지기만 할 뿐 따로 재생성되는 구역이 없다. DynamicModifiers Only는 빼기의 성격이 강함.Navigation InvokerInvoker = 명사 : 호출자, 초대자
Dynamic 설정을 통해 일부분 못지나가거나 새로 이동 가능한 구역을 타의 오브젝트위로 설정을 할 순 있지만 Mesh 자체의 이동과 사이즈가 동적으로 변경이 불가능하기 하다. 그래서 맵 전체를 Navmesh Bound Volume로 덮어야 하는가? 하는 의문이 생기게 된다. 이것은 플레이어가 가지않는 부분도 Navmesh 영역으로 설정될 수 있기 때문에 매우 비효율적이고 최적화의 관점에서도 좋지 않다. 이런 부분을 회피할 수 있는 기능이 Navigation Invoker이다.
Navigation Invoker는 Navigation Invoker라는 컴포넌트를 가진 액터의 주변 영역만 연산해서 리소스를 아끼고, 게임 플레이는 문제없이 가능하게 하는 기능이다.
캐릭터 클래스에 Navigation Invoker Component를 추가하여야한다.
// 헤더 추가
#include "NavigationInvokerComponent.h"
.
.
.
class AAI_TestCharacter : public ACharacter
{
GENERATED_BODY()
.
.
/** Navigation Invoker component */
UPROPERTY(BlueprintReadWrite, Category = "Navigation", meta = (AllowPrivateAccess = "true"))
UNavigationInvokerComponent* NavInvoker;
.
.
public:
AAI_TestCharacter();
float NavGenerationRadius;
float NavRemovalRadius;
/** Returns NavInvoker subobject **/
FORCEINLINE class UNavigationInvokerComponent* GetNavInvoker() const { return NavInvoker; }
}
meta = (AllowPrivateAccess = "true")생성자에 추가
// 활성화될 범위 설정. 테스트를 위해 매우 작은 값 부여.
NavGenerationRadius = 10.0f;
NavRemovalRadius = 15.0f;
// Navigation Invoker 컴포넌트 생성 및 초기값 셋업.
NavInvoker = CreateDefaultSubobject<UNavigationInvokerComponent>(TEXT("NavInvoker"));
// SetGenerationRadii 함수를 사용하여 생성 반경과 제거 반경 설정. Protected 멤버변수이므로 함수를 통해 수정 필요.
NavInvoker->SetGenerationRadii(NavGenerationRadius, NavRemovalRadius);
using UnrealBuildTool;
public class AI_Test : ModuleRules
{
public AI_Test(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
"Engine",
"InputCore",
"EnhancedInput",
"NavigationSystem"
});
}
}
해당 C++ 클래스를 상속받는 블루프린트 Character의 컴포넌트에 Nav Invorker가 추가된것을 확인할 수 있다.

🔥 주의

Navigation Invorker는 우선 Navmesh 안에서 Invorker 주변에 AI 이동영역을 계산하여 활성화하는 형식이다.
따라서 NevmeshBoundVolume 의 크기를 늘리고 Invorker Component를 가지고있는 캐릭터를 이동하면 이동영역이 활성화 되는 곳이 바뀌는 것을 확인할 수 있다.

👉 Navmesh가 레벨 전체를 감싸고 있더라도 실제로 연산되는 구역은 Invorker를 가지고 있는 주변으로만 제한되기 때문에 훨씬 효율적이라고 볼 수 있다.

