적 캐릭터
언리얼 엔진에서 NPC 적은 일반적으로 컨트롤러와 폰이 있다는 점에서 플레이어와 매우 비슷하게 구성됩니다. 실제로 적과 플레이어는 공통 베이스 클래스인 AParrotCharacterBase에서 몇 가지 함수 기능을 공유합니다. 패럿 게임에서는 비헤이비어 트리를 사용하여 적의 행동을 제어하므로, AI 컨트롤러 클래스를 사용하여 적 컨트롤러를 생성합니다. 적들 간에 해당 구성이 공유되는 애니메이션 블루프린트부터 시작하겠습니다.
적 애니메이션 블루프린트
애니메이션 블루프린트 템플릿
애니메이션에 대한 요구사항이 같은 스켈레탈 메시가 여러 개 있는 경우, 애니메이션 블루프린트 템플릿(Animation Blueprint Linking 참조)을 생성할 수 있습니다. 패럿의 경우, 머리 없는 해골, 해골, 상어, 보스 상어, 이렇게 네 가지 타입의 적이 등장합니다. 모두 동일한 스켈레톤과 애니메이션 환경설정을 공유하기 때문에 애니메이션 그래프와 이벤트 그래프를 구현하는 하나의 템플릿을 모든 적에 재사용할 수 있습니다. 이 템플릿이 어떻게 구성되는지는 Blueprints > Enemy > EnemyBase > ABT_EnemyBase에서 확인할 수 있습니다. 템플릿이 해당 애니메이션 블루프린트와 거의 동일한 방식으로 구성되어 있기 때문에 플레이어의 애니메이션 블루프린트와 매우 비슷하게 보입니다.
애니메이션 블루프린트
이 경우 모든 구현이 템플릿에 포함되어 있지만, 템플릿이 특정 스켈레톤을 참조하지 않기 때문에 애니메이션 자체는 없습니다. 각 적에는 이 템플릿에서 파생된 자체 애니메이션 블루프린트가 있으며, 각 블루프린트에는 해당 스켈레톤의 애니메이션이 애니메이션 그래프 오버라이드로 할당되어 있습니다. 예시는 Blueprints > Enemy > HeadlessSkeleton > ABP_Enemy_HeadlessSkeleton에서 확인할 수 있습니다.
아래에서는 머리 없는 해골의 스켈레탈 메시에 대해 각 애니메이션 스테이트에 적절한 애니메이션을 선택했습니다.
적 폰
패럿의 적 캐릭터는 플레이어와 많은 기능을 공유하며, 특히 사망과 같은 비슷한 기능과 히트포인트를 공유합니다. 이 공유 구현은 AParrotCharacterBase에서 확인할 수 있습니다. 적 전용 구현을 위해 AParrotEnemyCharacterBase 서브클래스가 있습니다. 이 서브클래스는 순찰 시스템 작동 방식, 전투 작동 방식 등의 모든 구현을 처리합니다. 전투 작동 방식에 대한 자세한 내용은 패럿의 전투 문서에서 확인할 수 있습니다.
이 구성에서 타격 및 피격 확인은 적 캐릭터에서 이루어지며, 볼륨을 트리거하는 방법에 대한 구현은 Blueprints > Enemy > EnemyBase > BP_EnemyCharacter_Base에 있는 블루프린트 베이스 클래스에서 확인할 수 있습니다.
이 구현이 네이티브 C++ 클래스에서 처리되지 않고 블루프린트에서 처리된 이유는 적마다 메시 형태, 크기, 복잡도가 다르기에 트리거 볼륨도 각각 달라야 하기 때문입니다. 이는 상속된 트리거 볼륨은 파생 클래스에서 수정할 수 없기 때문에 필요합니다.
적 AI 컨트롤러
앞서 언급했듯이 적은 비헤이비어 트리로 제어되므로 AParrotEnemyAIControllerBase의 AIController에서 파생된 베이스 클래스가 있습니다. 여기에서 비헤이비어 트리에서 사용할 데이터를 블랙보드에 전송하기 위해 사용되는 다양한 BlueprintImplementableEvents를 볼 수 있습니다.
AI 컨트롤러가 비헤이비어 트리에 데이터를 전달하는 방식과 플레이어 현재상태 탐지를 처리하는 방식은 Blueprints > AI > EnemyBase > BP_EnemyController_Base에서 확인할 수 있습니다.
비헤이비어 트리로 AI 생성하기
언리얼 엔진은 비헤이비어 트리를 사용하여 AI를 빌드할 수 있는 강력하고 유연한 인프라를 제공합니다. 몇 가지 행동으로 기본 보일러플레이트를 구성하는 퀵스타트 가이드는 비헤이비어 트리 퀵 스타트 가이드에서 확인할 수 있습니다. 해당 가이드의 결과를 기반으로 삼아 일부 수정을 통해 필요한 행동을 구성하여 적 AI를 생성했습니다.
플레이어 순찰 및 공격에 필요한 기본 기능을 제공하기 위해 Blueprints > AI > EnemyBase > BTT_FindNextPatrol 및 Blueprints > AI > EnemyBase > BTT_AttackPlayer, 이렇게 두 가지 비헤이비어 트리 태스크가 있습니다. 각 적에 모든 기능을 지원하는 인프라가 존재하기 때문에 공통 블랙보드는 Blueprints > AI > EnemyBase > BB_Enemy_Base 하나뿐입니다. 어떤 기능을 사용하여 적의 행동을 커스터마이징할지는 비헤이비어 트리 구현에 따라 결정됩니다.
각 적의 비헤이비어 트리 환경설정이 다르므로 적마다 다른 방식으로 행동합니다. 다음 위치에서 네 가지 비헤이비어 트리를 모두 살펴볼 수 있습니다.
Blueprints> AI > HeadlessSkeleton > BT_HeadlessSkeleton
Blueprints > AI/Skeleton > BT_Skeleton
Blueprints > AI > Sharky > BT_Sharky
Blueprints > AI > BossShark > BT_Boss_Shark
작성 가능한 순찰 웨이포인트 시스템 생성하기
적의 경우, 패럿에서는 비헤이비어 트리 가이드에서 보여주는 것과 같은 순찰 기능(적 AI가 4초마다 반경 내에서 탐색 가능한 지점을 무작위로 선택하는 기능)이 필요 없습니다. 다른 많은 플랫포머 게임처럼 능동적으로 순찰 경로를 따라 앞뒤로 순찰하는 적들이 필요합니다.
이를 위해 패럿에서는 필요한 기능을 제공하는 자체 시스템을 만들었습니다. 이 시스템은 씬에 배치하여 순찰 경로를 작성할 수 있는 UParrotEnemyPatrolRigComponent로 구성되어 있습니다. 이 컴포넌트는 클래스 디폴트 서브오브젝트를 사용하여 스플라인을 인스턴스화합니다. 이 스플라인을 사용하여 순찰 웨이포인트와 두 개의 트리거 볼륨(AI 행동 트리거에 사용됨), 웨이포인트의 순서를 그리는 에디터 전용 시각화 툴을 작성합니다. 웨이포인트의 순서를 지정하면 편집 시 순찰 경로의 방향을 확인할 수 있습니다. C++ 구현에 대한 자세한 내용은 UParrotEnemyPatrolRigComponent에서 확인할 수 있습니다.
이 구현은 컴포넌트이므로 씬의 어떤 액터에든 순찰 릭을 어태치할 수 있습니다. 이렇게 하면 움직이는 오브젝트에 릭을 배치할 수 있어, 로컬 공간에서 순찰 경로가 계속 올바르게 배치됩니다. 씬에 기존 액터에 어태치되지 않은 순찰 릭을 배치하기 위해 AParrotEnemyPatrolRigActor를 사용합니다. 이 액터는 씬의 어느 곳에나 배치할 수 있으며, 그 자체에 디폴트 서브오브젝트로 UParrotEnemyPatrolRigComponent를 스폰합니다.
이 구현을 사용하면 런타임에 스폰할 적을 선택하여 순찰 경로를 따라다니게 할 수 있습니다. 이 프로세스에서는 디퍼드 액터 스폰이라는 언리얼 엔진 기능을 사용합니다. 이 기능을 사용하면 두 단계로 액터를 스폰할 수 있는데, 첫 번째 단계에서는 BeginPlay와 같은 AActor 초기화를 수행하지 않고 액터 오브젝트를 생성합니다. 이를 통해 액터가 초기화되기 전에 필요한 모든 환경설정이나 구성을 수행할 수 있습니다. 이 구성을 수행한 다음에는 두 번째 단계를 호출하여 스폰을 마무리하고 액터를 초기화합니다. 이 작업은 순찰 릭을 위해 수행됩니다. 즉, 적 액터가 스폰될 때 순찰 스플라인과 트리거 볼륨이 액터에 파이프로 전달되어 액터 초기화 중에 처리되고 순찰 시퀀스가 자동으로 시작될 수 있도록 하기 위함입니다.
디퍼드 액터 스폰을 수행하는 코드는 UParrotEnemyPatrolRigComponent에서 확인할 수 있습니다. 블루프린트에도 비슷한 기능이 있는데, 블루프린트 액터의 프로퍼티에 스폰 시 노출(Expose on Spawn) 태그를 지정하면 액터의 초기화가 진행되기 전에 설정된 실행인자를 스폰 블루프린트 노드에 전달할 수 있습니다.
아래 그림에서는 Maps > Level_1 > Level_1에 구성된 순찰 릭의 예시를 볼 수 있으며, 오른쪽 0지점부터 시작하는 두 지점의 순찰 릭이 있습니다. 이 순찰 릭은 BP_EnemyCharacter_Skeleton을 스폰하도록 구성되어 있습니다.
아래에는 편집 시 순찰 릭 웨이포인트를 쉽게 식별할 수 있게 해주는 표시 플래그(Show Flag) 토글 메뉴가 있습니다. 대부분의 표시 플래그 체크박스가 선택되어 있습니다. 에디터 전용 시각화 툴 컴포넌트인 UParrotPatrolRigDebugVisualizer에서 표시 플래그의 구현 방법을 확인할 수 있습니다.