인바이런먼트 쿼리 시스템 퀵스타트 가이드

인바이런먼트 쿼리 시스템 퀵스타트 가이드는 EQS 및 AI로 작업하는 데 필요한 시스템과 툴을 빠르게 습득하도록 지원합니다.

Choose your operating system:

Windows

macOS

Linux

이 가이드를 진행하기에 앞서 비헤이비어 트리 퀵스타트 가이드를 진행하거나 언리얼 엔진 5의 블루프린트 및 비헤이비어 트리에 대한 사전 지식을 습득하실 것을 권장합니다.

인바이런먼트 쿼리 시스템(Environment Query System, EQS)비헤이비어 트리(Behavior Tree) 내에서 다양한 테스트(Test)를 통해 환경을 조사하고 테스트 결과를 베이스로 어떻게 진행할지 결정할 수 있습니다. EQS 사용 사례로는 AI 캐릭터가 레벨에서 플레이어로부터 엄폐할 위치를 찾게 하거나, 가장 가까운 체력 아이템 또는 탄약을 찾게 하는 것 등을 예로 들 수 있습니다.

인바이런먼트 쿼리는 사실 여러 부분으로 이루어집니다. 비헤이비어 트리에서 인바이런먼트 쿼리를 호출하면, 실제 인바이런먼트 쿼리는 해당 제네레이터(Generator)를 사용하고 컨텍스트(Context)를 참조한 후 테스트를 사용하여 비헤이비어 트리에 가장 높은 가중치가 적용된 결과를 제공합니다.

이 가이드에서는 플레이어가 보일 때까지 환경 곳곳을 랜덤하게 돌아다니는 AI를 만들겠습니다. 플레이어를 보면 AI는 EQS 시스템으로 플레이어와의 거리를 유지하면서 환경 내에서 가장 유리한 위치를 찾을 것입니다. 이는 AI 캐릭터가 원거리 공격을 수행하게 하거나, 아래 예시와 같이 AI가 플레이어로부터 거리를 유지하면서 시야를 확보하게 하려는 경우 유용합니다.

가이드에 따라 학습을 마치면 다음과 같은 시스템의 기초를 이해할 수 있습니다.

  1. 블루프린트 비주얼 스크립팅(Blueprint Visual Scripting)

  2. AI 컨트롤러(AI Controller)

  3. 블랙보드(Blackboard)

  4. 비헤이비어 트리

  5. 인바이런먼트 쿼리 시스템(Environmental Query System, EQS)

  6. EQS 컨텍스트(EQS Context)

  7. AI 디버깅 툴(AI Debugging Tool)

1 - 필수 프로젝트 구성

이 단계에는 AI에 필요한 에셋으로 프로젝트를 구성하고 EQS 시스템을 활성화합니다.

이 가이드에서는 새로운 블루프린트 삼인칭 템플릿(Blueprint Third Person Template) 프로젝트를 사용합니다.

  1. 필요하면 프로젝트 내의 세팅(Settings) > 플러그인(Plugins) 섹션에서 인바이런먼트 쿼리 에디터(Environment Query Editor) 옵션을 활성화합니다.

    프로젝트 세팅에서 인바이런먼트 쿼리 에디터 활성화

    EQS 시스템을 활성화하면 EQS 관련 에셋을 생성하고 에셋에 액세스할 수 있습니다.

  2. 콘텐츠(Content) > ThirdPerson > Blueprints 폴더로 가서 BP_ThirdPersonCharacterAI 라는 새 폴더로 복사합니다.

    BPThirdPersonCharacter를 AI라는 새 폴더로 복사

  3. AI 폴더에서 +추가(+Add) > 고급 에셋 생성(Create Advanced Asset) > 인공 지능(Artificial Intelligence) 옵션을 선택하여 다음과 같이 세 가지 AI 에셋을 생성합니다.

    AI 폴더의 추가 옵션에서 다음과 같이 세 가지 AI 에셋 생성

    • 블랙보드(Blackboard) 를 생성하여 BB_Enemy 로 명명

    • 비헤이비어 트리(Behavior Tree) 를 생성하여 BT_Enemy 로 명명

    • 인바이런먼트 쿼리(Environment Query) 를 생성하여 EQS_FindPlayer 로 명명

  4. AI 컨트롤러(AIController) 타입의 새 블루프린트 클래스(Blueprint Class) 를 생성하여 AIC_Enemy 로 명명합니다.

    AI 컨트롤러 타입의 새 블루프린트 클래스를 생성하여 AIC_Enemy로 명명합니다

  5. 인바이런먼트 쿼리 컨텍스트 블루프린트 베이스(EnvQueryContext_BlueprintBase) 타입의 새 블루프린트 클래스 를 생성하고 EQC_PlayerContext 로 명명합니다.

    EnvQueryContextBlueprintBase 타입의 새 블루프린트 클래스를 생성하고 EQC_PlayerContext로 명명합니다

    컨텍스트(Context) 는 EQS 시스템에서 다양한 테스트를 적용할 때 레퍼런스로 사용됩니다. 예를 들어 '지정된 컨텍스트에 얼마나 가까운지 파악'하는 테스트를 실행할 수 있습니다. 가이드의 조금 뒷부분에서 이 에셋을 사용하여 플레이어 캐릭터를 테스트 수행의 컨텍스트로 제공합니다.

2 - 인바이런먼트 쿼리 컨텍스트

이 단계에는 가이드 뒷부분의 테스트에 사용할 플레이어 캐릭터의 EQS 시스템을 위한 컨텍스트(Context)를 준비합니다.

  1. EQC_PlayerContext 에셋을 열고 내 블루프린트(My Blueprint) 패널에서 Provide Single Actor 함수를 오버라이드합니다.

    내 블루프린트 패널에서 Provide Single Actor 함수를 오버라이드합니다

    컨텍스트로는 개별 액터(Actor) 또는 위치(Location) 를 제공하거나 액터 또는 위치 세트를 제공할 수 있습니다.

  2. Provide Single Actor 함수의 Resulting ActorGet Player Character 호출을 사용합니다.

    Resulting Actor로 Get Player Character 호출을 사용

    이렇게 하면 런타임에 플레이어 캐릭터를 컨텍스트로 얻습니다.

    여기서는 블루프린트에 집중하지만, 더 최적화된 접근법은 C++로 컨텍스트를 생성하는 것입니다.

3 - EQS 구성

이 단계에는 EQS 에디터를 열고 플레이어 캐릭터에 대한 시야가 확보되는 위치를 찾는 테스트(Test)를 구성합니다.

  1. EQS_FindPlayer 내의 루트(Root) 노드에서 그래프로 드래그하여 Points: Grid 노드를 추가합니다.

    루트 노드에서 그래프로 드래그하여 Points: Grid 노드를 추가합니다

    컨텍스트와 관련된 아이템(Item) 을 생성하는 제네레이터(Generator) 에는 여러 타입이 있습니다. 생성한 아이템은 테스트에 사용됩니다(예시: 컨텍스트 Y로부터 아이템 X까지의 거리 측정). 아이템은 테스트 결과에서 컬링되거나 점수화되어 '최적'(가장 높거나 가장 낮은 점수)의 옵션이 무엇인지 결정하는 데 사용됩니다.

    이 예시에서는 AI 주변 그리드에 AI가 위치하면 플레이어 캐릭터를 볼 수 있는 일련의 포인트를 생성합니다.

  2. 디테일(Details) 패널에서 그리드 절반 크기(GridHalfSize)800 으로, 사이 공간(Space Between)150.0 으로 변경합니다.

    디테일 패널에서 그리드 절반 크기를 800으로, 사이 공간을 150.0으로 변경합니다

    이 두 세팅은 테스트할 포인트의 개수와 포인트 사이의 거리를 정의하는 데 사용됩니다. 퍼포먼스를 위해서는 감당할 수 있는 규모로 유지해야 합니다. 그리드가 너무 크면 게임 퍼포먼스에 영향을 미칠 수 있습니다.

    중심으로 생성(Generate Around) 필드를 사용하여 그리드를 어디에 배치할지 결정할 수 있습니다. 이 경우 쿼리 요청자 또는 AI 캐릭터 주변으로 합니다. 주변 생성(Generate Around) 에서 앞서 만든 플레이어 컨텍스트를 사용하도록 설정해도 되지만, AI가 이미 플레이어에 대한 시야를 확보했다면 플레이어 근처의 그리드 포인트로 이동하지 않게 해야 합니다.

    투영 데이터(Projection Data) 옵션은 그리드가 생성되는 방식을 결정하는 추가 필드를 제공합니다. 이 예시에서는 디폴트 상태로 두겠지만, 원한다면 나중에 돌아와서 조정해도 됩니다.

  3. SimpleGrid 노드를 우클릭하고 테스트 추가(Add Test) 에서 Trace 를 선택합니다.

    SimpleGrid 노드를 우클릭하고 테스트 추가에서 Trace를 선택합니다

    Trace 테스트는 그리드의 포인트가 플레이어 캐릭터를 볼 수 있는지 정하는 데 사용됩니다.

    제네레이터에 테스트를 추가하는 순서는 결과와 무관합니다. 테스트는 후속 테스트에서 최대한 적은 수의 아이템 컬렉션을 처리하도록 먼저 필터를 적용한 뒤 비용을 기준으로도 필터를 적용하는 순서입니다. 따라서 거리 필터가 시야 필터보다 먼저 실행됩니다.

  4. 우클릭하고 Distance 타입의 테스트를 추가합니다.

    우클릭하고 Distance 타입의 테스트를 추가합니다

    Trace 테스트가 플레이어 캐릭터를 볼 수 있는 포인트를 반환한 후에 Distance 테스트가 사용되어 플레이어 캐릭터와의 근접성을 베이스로 이 포인트를 점수화합니다.

  5. Trace 테스트를 선택하고 디테일(Details) 패널에서 옵션을 다음과 같이 설정합니다.

    Trace 테스트를 선택하고 디테일 패널에서 옵션을 다음과 같이 설정합니다

    • 테스트 목적(Test Purpose) = 필터만(Filter Only)

    • 컨텍스트(Context) = EQC_PlayerContext

    • Bool 일치(Bool Match) = 비활성화

    플레이어 캐릭터가 보이는지에 대한 Trace 테스트의 레퍼런스 포인트(컨텍스트)를 제공하는 것입니다. Bool 일치 옵션을 비활성화하면 플레이어 캐릭터를 볼 수 없는 포인트가 필터로 걸러집니다.

  6. Distance 테스트를 선택하고 디테일(Details) 패널에서 테스트 목적점수만(Score Only) 으로 변경한 후 스코어 인수(Scoring Factor)-1.0 으로 변경합니다.

    디테일 패널에서 테스트 목적을 점수만으로 변경한 후 스코어 인수를 -1.0으로 변경합니다

    Distance 테스트의 목적은 반환된 아이템을 점수화하는 것이며, 스코어 인수 -1.0은 플레이어 캐릭터로부터 더 가까운 포인트에 점수를 부여합니다. 스코어 인수를 1.0으로 두면 플레이어로부터 가장 멀리 떨어진 포인트를 반환합니다. 그러면 AI가 가장 먼 포인트에 도달하기 위해 플레이어 캐릭터를 지나쳐서 달려갈 수도 있습니다.

    그 밖에도 점수의 범위를 최댓값 또는 최솟값으로 제한하거나, 점수 계산식(Scoring Equation) 을 변경하여 스코어 인수 를 곱하기 전에 정규화된 점수에 적용할 커브 계산식을 변경하거나, 정규화 타입(Normalization Type) 을 정의하거나, 점수의 정규화에 사용되는 레퍼런스 값(Reference Value) 을 할당하는 등의 점수화 옵션이 있습니다. 이 예시에서는 모두 디폴트 세팅으로 둡니다.

4. 블랙보드 및 비헤이비어 트리 구성

이 단계에는 블랙보드 키(Blackboard Key)와 비헤이비어 트리의 분기 레이아웃을 구성합니다.

  1. BB_Enemy 블랙보드 에셋 내에서 다음과 같이 세 가지 키를 생성합니다.

    BB_Enemy 블랙보드 에셋 내에서 다음과 같이 세 가지 키를 생성합니다

    • 부울(Bool) 키를 생성하여 HasLineOfSight 로 명명

    • 벡터(Vector) 키를 생성하여 MoveToLocation 로 명명

    • 오브젝트(Object) 키를 생성하여 TargetActor 로 명명하고 베이스 클래스(Base Class)Actor 로 설정

    이 키들은 비헤이비어 트리의 분기를 업데이트하고 분기 사이에서 이동하는 데 사용될 것입니다.

  2. BT_Enemy 비헤이비어 트리를 열고 Selector , Sequence , Wait 태스크 노드를 사용하여 다음과 같이 그래프를 생성합니다.

    이미지를 클릭하면 최대 크기로 볼 수 있습니다.

    위 예시에는 세 개의 주요 분기가 있습니다. 가장 왼쪽 분기는 In Combat 으로 명명한 Selector 노드를 사용하여 두 Sequence 노드 사이를 전환합니다. 둘 중 하나는 Attack 으로, 다른 하나는 Move into Position 으로 명명했습니다. AI가 'In Combat' 분기를 실행하는 중이 아니라면, Patrolling 이라고 명명한 다음 분기를 실행합니다. 어떤 이유에서 AI가 전투 중도, 순찰 중도 아닐 경우 다음 분기로 넘어가려고 시도하기 전에 실패하지 않도록 대기하는 태스크를 넣고 대기 시간을 1초로 설정했습니다.

5 - 비헤이비어 트리: 순찰 구성

이 단계에는 비헤이비어 트리의 Patrolling 분기를 구성합니다.

  1. Patrolling 시퀀스 노드에서 드래그하여 Move To 태스크(블랙보드 키를 MoveToLocation 으로 설정) 및 Wait 태스크 (대기 시간과 편차를 5 +/- 1 초로 설정)를 추가합니다.

    Patrolling 시퀀스 노드에서 Move To 태스크와 Wait 태스크를 추가합니다

    이러면 AI가 블랙보드 키 MoveToLocation 으로 이동한 후 지정된 시간 동안 기다리게 합니다. 하지만 MoveToLocation 의 벡터 값을 아직 정의하지 않았습니다.

  2. 툴바에서 새 태스크(New Task) 를 생성하고 콘텐츠 브라우저(Content Browser) 에서 BTT_RandomLocation 으로 명명합니다.

    툴바에서 새 태스크를 생성하고 콘텐츠 드로어에서 BTT_RandomLocation으로 명명합니다

  3. BTT_RandomLocation 내에서 다시 아래와 같이 블루프린트 그래프를 만듭니다.

    이벤트 Receive Execute AI 노드를 사용하여 Controlled PawnGet Actor Location 을 연결하고, 이 노드를 GetRandomReachablePointinRadius 함수의 Origin 으로 사용합니다(Radius1000 으로 설정했습니다).

    GetRandomReachablePointInRadius 노드의 Return ValueBranchCondition 으로 사용합니다. True 핀에 Random Location 값과 Set Blackboard Value as Vector 를 사용하고, Key 에는 Blackboard Key Selector 변수(MoveToLocation 으로 명명)를 연결합니다.

    False 핀에 Set Blackboard Value as Vector 를 연결하고 ValueGet Actor Location 을 연결합니다. 랜덤 포인트가 발견되지 않은 경우, 새 위치를 찾기 전에 캐릭터의 기존 위치를 가져옵니다. Finish Execute 노드를 Success 가 활성화된 상태로 두 실행 와이어와 연결하여 태스크를 종료합니다.

    이 블루프린트를 비헤이비어 트리에 태스크로 추가하기 전에 MoveToLocation 값을 설정할 수 있어야 하므로, 내 블루프린트(My Blueprint) 패널의 눈 모양 아이콘을 클릭하여 인스턴스 편집가능(Instance Editable) 으로 설정합니다.

    내 블루프린트 패널의 눈 모양 아이콘을 클릭합니다

  4. 비헤이비어 트리에서 BTT_RandomLocation 태스크를 Patrolling 아래의 첫 노드로 추가하고, 디테일(Details) 패널에서 MoveToLocation 을 설정합니다.

    비헤이비어 트리에 BTT_RandomLocation 태스크를 추가합니다

6 - 비헤이비어 트리: 전투 중 구성

이 단계에는 In Combat 분기와 관련된 태스크를 구성하고, 플레이어 캐릭터에 대한 시야가 확보되는 위치를 찾는 EQS_FindPlayer 쿼리를 포함합니다.

  1. In Combat 셀렉터(Selector)를 우클릭하고 Blackboard 타입의 데코레이터(Decorator) 를 추가하여 다음과 같이 설정합니다.

    In Combat 셀렉터를 우클릭하고 Blackboard 타입의 데코레이터를 추가합니다

    • 관찰자 중단(Observer aborts)Lower Priority 로 설정

    • 블랙보드 키(Blackboard Key)TargetActor 로 설정

    TargetActor가 설정되면 In Combat 분기를 실행하고 우선순위가 낮은 태스크를 종료하도록 설정하는 것입니다.

  2. Attack 시퀀스(Sequence)를 우클릭하고 Blackboard 타입의 데코레이터(Decorator) 를 추가하여 다음과 같이 설정합니다.

    Attack 시퀀스를 우클릭하고 Blackboard 데코레이터를 추가합니다

    • 관찰자 노티파이(Notify Observer)On Value Change 로 설정

    • 관찰자 중단(Observer aborts)Lower Priority 로 설정

    • 블랙보드 키(Blackboard Key)HasLineOfSight 로 설정

    HasLineOfSight 가 설정된 경우 Attack 분기를 실행하도록 명령하는 것입니다. HasLineOfSight 가 설정되지 않은 경우 HasLineOfSight 가 다시 설정될 때까지 다른 분기를 실행합니다.

  3. Attack 노드에서 드래그하여 Rotate to face BB entry 를 추가하고 블랙보드 키를 TargetActor 로 설정합니다.

    Attack 노드에서 Rotate to face BB entry를 추가합니다

    이렇게 하면 AI가 'Attack' 분기 상태일 때 TargetActor를 향해 회전합니다. 이 예시에서는 AI에 부여할 공격을 만들지 않았지만, 원한다면 나중에 추가해도 좋습니다.

  4. Move Into Position 노드에서 드래그하여 Run EQSQuery 노드를 사용합니다.

    Move Into Position 노드에서 드래그하여 Run EQSQuery 노드를 사용합니다

    Run EQSQuery 노드로는 할당된 블랙보드 키를 업데이트할 EQS 쿼리를 실행할 수 있습니다.

  5. Run EQSQuery 노드의 디테일(Details) 패널에서 블랙보드 키(Blackboard Key)MoveToLocation 으로 설정하고 쿼리 템플릿(Query Template)EQS_FindPlayer 로 설정합니다.

    블랙보드 키를 MoveToLocation으로 설정하고 쿼리 템플릿을 EQSFindPlayer로 설정합니다

  6. Run EQSQuery 뒤에 Move To (블랙보드 키는 MoveToLocation 으로 설정)와 Rotate to face BB entry (블랙보드 키는 TargetActor 로 설정)를 추가합니다.

    Run EQSQuery 뒤에 MoveTo와 Rotate to face BB entry를 추가합니다

    비헤이비어 트리가 EQS 쿼리를 실행하여 블랙보드 키 MoveToLocation 을 업데이트하면 AI는 해당 위치로 이동해서 플레이어 캐릭터인 TargetActor 를 향해 회전할 것입니다.

    전체 비헤이비어 트리의 모습은 다음과 같습니다.

    이미지를 클릭하면 최대 크기로 볼 수 있습니다.

7 - AI 컨트롤러 구성

이 단계에는 비헤이비어 트리를 실행할 AI 컨트롤러를 구성하고 AI가 AI 퍼셉션(AI Perception)을 사용하여 플레이어 캐릭터를 볼 수 있게 합니다.

  1. AIC_Enemy 블루프린트 내에 이벤트 On Possess 를 추가하고 Run Behavior Tree 에 연결합니다. BTAsset은 BT_Enemy 로 설정합니다.

    이벤트 On Possess를 추가하고 Run Behavior Tree에 연결합니다

  2. AI 인지 컴포넌트(AIPerception Component) 를 추가하고, AI 시야 구성(AI Sight config) 세팅을 추가합니다.

    AI 인지 컴포넌트를 추가하고, 다음 AI 시야 구성 세팅을 추가합니다

    • 감지 환경설정(Senses Config)AI 시야 구성 추가

    • 중립 탐지(Detect Neutrals)활성화

    이렇게 하면 퍼셉션 시스템에 액터가 인지될 때 AI가 다른 액터를 감지하고 이벤트를 실행합니다. 현재는 기본적으로 플레이어에게 소속이 할당되지 않으며, C++ 코드로만 소속을 할당할 수 있습니다. 이를 우회하기 위해 퍼셉션 시스템이 중립 소속을 탐지하게 하고, 액터 태그를 사용하여 'Player' 태그가 설정된 액터만 인지하게 할 것입니다.

  3. AI 인지 컴포넌트(AIPerception Component)이벤트(Events) 에서 타깃 퍼셉션 업데이트 시(On Target Perception Updated) 를 추가하고 Actor 핀을 Perceived Actor 라는 변수로 승격합니다.

    이미지를 클릭하면 최대 크기로 볼 수 있습니다.

    AI가 인지한 액터는 변수로 저장되며, 나중에 블랙보드를 업데이트할 때 그 변수를 사용합니다.

  4. Branch 노드를 2개 추가하고 다음과 같이 조건을 설정합니다.

    이미지를 클릭하면 최대 크기로 볼 수 있습니다.

    • 첫 번째 Branch의 ConditionActor Has Tag 로 설정하고 TagPlayer 를 입력합니다. 타깃(Target)타깃 퍼셉션 업데이트 시(On Target Perception Updated)Actor 로 합니다.

    • 두 번째 Branch의 Condition타깃 퍼셉션 업데이트 시 이벤트의 Stimulus 핀에서 Successfully Sensed 로 설정합니다.

    위 예시에서는 인지된 액터에 Player 태그가 있는 경우 Branch가 해당 액터가 성공적으로 감지되었는지 여부를 확인합니다. 액터에 태그가 없는 경우(예를 들어 다른 적인 경우) 진행하지 않습니다.

  5. 두 번째 Branch의 False 핀에서 드래그하여 아래 3개의 노드를 추가합니다.

    두 번째 Branch의 False 핀에서 드래그하여 아래 3개의 노드를 추가합니다

    위 예시에서는 Set Timer by Event 노드(Time은 8.0 으로 설정)를 추가하고, Return ValueLostSightTimer 라는 변수로 승격했습니다. 그런 다음 LostSight 라는 커스텀 이벤트를 Event 델리게이트에 할당했습니다.

  6. 내 블루프린트(My Blueprint) 패널에서 함수 2개를 생성하고, UpdateSightKeyUpdateTargetKey 로 명명합니다.

    내 블루프린트 패널에서 UpdateSightKey와 UpdateTargetKey 함수를 생성합니다

    이 두 함수로는 비헤이비어 트리의 의사 결정에 사용되는 블랙보드 키를 업데이트할 것입니다.

  7. UpdateSightKeyHasLineOfSight 라는 부울 입력을 추가합니다.

    HasLineOfSight라는 부울 입력을 추가합니다

  8. UpdateSightKey 내에서 우클릭하여 Get Blackboard 변수와 Set Value as Bool 을 추가합니다. Key NameHasLineOfSight 로 합니다.

    UpdateSightKey 내에서 우클릭하여 Get Blackboard 변수와 Set Value as Bool을 추가합니다. Key Name은 HasLineOfSight로 합니다

    그러면 이 함수로 부울 값을 블랙보드 키에 전달하고 HasLineOfSight 키를 업데이트할 수 있습니다.

  9. UpdateTargetKeyTargetActor 라는 액터(Actor) 입력을 추가합니다.

    UpdateTargetKey에 TargetActor라는 액터 입력을 추가합니다

  10. UpdateTargetKey 내에서 우클릭하여 Get Blackboard 변수와 Set Value as Object 를 추가합니다. Key NameTargetActor 로 합니다.

    UpdateTargetKey 내에서 우클릭하여 Get Blackboard 변수와 Set Value as Object를 추가합니다. Key Name은 TargetActor로 합니다

    UpdateSightKey 함수와 유사하게, 이 함수가 전달하는 액터로 블랙보드 키 TargetActor 가 업데이트됩니다.

  11. UpdateSightKeyUpdateTargetActor 함수를 False 조건에 다음과 같이 추가합니다.

    UpdateSightKey와 UpdateTargetActor 함수를 False 조건에 추가합니다

    AI 퍼셉션이 Player 태그가 있는 액터를 감지하지 못한 경우, false 조건이 타이머를 시작하고(나중을 위해 핸들에 저장하고) 블랙보드 키 HasLineOfSight 를 false로 업데이트합니다. 지정된 시간(8.0초)이 지난 뒤에는 커스텀 이벤트 LostSight 가 실행되어 TargetActor 블랙보드 키를 지웁니다(플레이어를 더 이상 타기팅하지 않으며 시야에서 놓친 것입니다).

    타이머의 Time 값을 조정하여 AI가 플레이어 캐릭터 추격을 '포기'하기까지의 시간을 미세조정할 수 있습니다.

  12. 두 번째 Branch의 True 핀에서 드래그하여 LostSightTimerClear and Invalidate Timer by Handle 을 사용합니다.

    두 번째 Branch의 True 핀에서 드래그하여 LostSightTimer와 Clear and Invalidate Timer by Handle을 사용합니다

    그러면 플레이어 캐릭터를 시야에서 놓쳤을 때 타이머가 정지되고 초기화됩니다.

  13. UpdateSightKey (활성화 설정)와 UpdateTargetKey (Perceived Actor 로 설정)를 추가합니다.

    UpdateSightKey와 UpdateTargetKey를 추가합니다

    최종 그래프는 아래와 유사할 것입니다.

    이미지를 클릭하면 최대 크기로 볼 수 있습니다.

    AI 컨트롤러가 구성되었고, 비헤이비어 트리를 실행하며, AI 퍼셉션 시스템으로 Player 태그가 있는 액터를 인지할 때 블랙보드 키를 업데이트합니다.

8 - 최종 구성

이 단계에는 적 AI 캐릭터 블루프린트를 구성하고, 플레이어 캐릭터 블루프린트에 Player 태그를 추가해서 AI가 인지할 수 있게 하고, NavMeshBoundsVolume과 메시를 추가하여 AI는 환경 내에서 어떻게 움직여야 할지 파악하고 플레이어는 시야에서 더 쉽게 벗어날 수 있게 합니다.

  1. BP_Enemy 를 열어 디테일(Details) 패널에서 컨트롤러 회전 요 사용(Use Controller Rotation Yaw) 을 활성화하고 AI 컨트롤러 클래스(AI Controller Class)AIC_Enemy 로 설정합니다.

    이미지를 클릭하면 최대 크기로 볼 수 있습니다.

    AI가 비헤이비어 트리 내에서 회전 태스크를 실행하게 하려면 컨트롤러 회전 요를 활성화해야 합니다. 우리가 만든 로직을 포함하고 비헤이비어 트리를 실행하는 커스텀 AI 컨트롤러 클래스도 할당합니다. 플레이어 캐릭터에서 복사된 스크립트와 카메라 컴포넌트는 AI 캐릭터에 필요하지 않으므로 모두 삭제해도 됩니다.

  2. 모드(Modes) 패널에서 NavMeshBoundsVolume 을 레벨에 추가하고 레벨을 감싸도록 스케일을 조절합니다.

    모드 패널에서 NavMeshBoundsVolume을 레벨에 추가하고 레벨을 감싸도록 스케일을 조절합니다

    P 를 눌러 이동 가능한 경로를 녹색으로 표시하는 디버그 그리드를 토글할 수 있습니다. 게임플레이 도중에는 show Navigation true (표시) 또는 false (숨김) 콘솔 명령을 사용할 수도 있습니다.

  3. 레벨에서 BP_ThirdPersonCharacter 를 우클릭하고 BP_ThirdPersonCharacter 편집(Edit BP_ThirdPersonCharacter) 을 선택합니다.

    레벨에서 BPThirdPersonCharacter를 우클릭하고 BPThirdPersonCharacter을 선택합니다

  4. 디테일(Details) 패널에서 태그(Tag) 를 찾고 Player 라는 태그 를 추가합니다.

    디테일 패널에서 태그를 찾고 Player라는 태그를 추가합니다

    AIC_Enemy 블루프린트 내에서 AI 퍼셉션 시스템이 액터를 인지하면, 이 액터에 Player 태그가 있으므로 Branch가 true로 평가됩니다.

  5. 레벨 내에서 스케일을 키우고 여러 버전의 큐브 메시(Cube Mesh) 를 추가하여 시야를 차단할 추가 엄폐 포인트를 제공합니다.

    스케일을 키우고 여러 버전의 큐브 메시를 추가하여 시야를 차단할 추가 엄폐 포인트를 제공합니다

  6. 툴바의 플레이(Play) 버튼을 눌러서 레벨에서 플레이합니다.

9 - 최종 결과물

에디터에서 플레이하면 AI는 플레이어가 보일 때까지 랜덤 위치를 순찰합니다. 플레이어를 보면 AI는 플레이어 방향으로 회전하고, 플레이어를 시야에서 놓칠 경우 새 위치로 이동하려 합니다. AI는 EQS를 사용하여 플레이어에 대한 시야가 확보되면서도 거리가 유지되는 위치를 찾을 것입니다. 새 위치로 이동하는 동안 플레이어가 보이지 않으면, 아래 비디오에서처럼 약간의 시간이 지난 뒤 추격을 포기하고 순찰로 돌아갑니다.

AI 디버깅 툴(AI Debugging Tool)을 사용하여 활성 EQS 쿼리를 확인할 수 있으며, 비헤이비어 트리나 퍼셉션 정보도 확인할 수 있습니다. 런타임에 AI 디버깅을 활성화하려면 ' (아포스트로피)를 누른 다음 1(일반 AI 디버깅), 2(비헤이비어 트리), 3(EQS), 4(AI 퍼셉션) 중 하나를 선택합니다. 아래 예시에서는 AI 디버깅을 활성화하고 EQS 디버깅 툴을 열었습니다.

EQS 디버깅 툴이 실행 중인 동안에는 그리드 테스트로 선택된 포인트를 점수 값과 함께 볼 수 있습니다. 또한 Winner 라는 텍스트로 어떤 포인트가 선택되었는지 알 수 있습니다. 이 툴은 점수 값을 베이스로 어떤 포인트가 평가되고 있는지, 어떤 포인트는 선택되고 어떤 포인트는 선택되지 않은 이유가 무엇인지 파악하는 데 유용합니다.

EQS 디버깅 툴 외에도 에디터 내에서 EQS 쿼리를 디버깅하는 데 사용할 수 있는 EQS 테스팅 폰(EQS Testing Pawn) 이라는 특수한 타입의 폰이 있습니다. 이 폰은 새 블루프린트 클래스(Blueprint Class)를 EQS 테스팅 폰 클래스로 생성하여 만들 수 있습니다.

이 폰은 새 블루프린트 클래스를 EQS 테스팅 폰 클래스로 생성하여 만들 수 있습니다

현재 설정에서 EQS의 테스트(Test)는 플레이어 캐릭터를 평가의 컨텍스트(Context)로 사용합니다. 게임을 실행하는 중이 아닐 때 테스트하려면 EQS_PlayerContext 블루프린트를 약간 수정하고 Provide Actors Set 함수를 오버라이드해야 합니다.

EQS_PlayerContext 블루프린트를 약간 수정하고 Provide Actors Set 함수를 오버라이드해야 합니다

다음과 같이 Get All Actors of Class 세트를 BP_ThirdPersonCharacter 로 설정하여 Resulting Actors Set 를 제공할 수 있습니다.

다음과 같이 Get All Actors of Class 세트를 BP_ThirdPersonCharacter로 설정하여 Resulting Actors Set를 제공할 수 있습니다

EQS 테스팅 폰을 레벨에 추가할 때 디테일(Details) 패널에서 쿼리 템플릿(Query Template) 을 할당할 수 있습니다. 여기서는 EQS_FindPlayer 쿼리로 설정했습니다.

디테일 패널에서 쿼리 템플릿을 할당할 수 있습니다

이렇게 하면 아래와 같이 에디터 내에서 테스트 결과를 볼 수 있습니다.

EQS 데이터는 VisLog로도 참조할 수 있도록 기록됩니다. 자세한 내용은 비주얼 로거(Visual Logger) 를 참고하세요.