PART 4 - 강의 2/3

EQS Test와 Context

Distance, Trace, Dot, Pathfinding 테스트와 Context 시스템의 활용법을 마스터합니다

01

EQS Test 기본 구조

Test의 역할, Scoring, Filter 모드

EQS Test는 Generator가 생성한 각 아이템에 점수를 부여하거나 필터링합니다. 하나의 EQS 쿼리에 여러 Test를 조합하여 복합적인 평가 기준을 만들 수 있습니다.

C++// Test 목적(Purpose) 설정 enum class EEnvTestPurpose : uint8 { Filter, // 조건 미충족 아이템 제거 Score, // 아이템에 점수 부여 FilterAndScore, // 필터 + 점수 둘 다 }; // Scoring 방정식 // FinalScore = Clamp(RawScore, ClampMin, ClampMax) // * ScoringFactor // Filter 타입 enum class EEnvTestFilterType : uint8 { Minimum, // 값 >= Threshold Maximum, // 값 <= Threshold Range, // Min <= 값 <= Max Match, // Bool/Enum 일치 }; // Scoring 방정식 타입 enum class EEnvTestScoreEquation : uint8 { Linear, // 선형: Score = Value Square, // 제곱: Score = Value^2 InverseLinear,// 역선형: Score = 1 - Value Constant, // 상수: Score = 1 (필터용) SquareRoot, // 제곱근: Score = sqrt(Value) }; // Test Weight: 여러 Test 점수의 가중치 // 예: Distance Weight=1.0, Trace Weight=2.0 // → Trace 결과가 2배 더 중요

먼저 Filter로 부적합한 후보를 제거하고, 남은 후보에 Score를 부여하는 것이 일반적입니다. Filter가 먼저 적용되면 Score 계산 대상이 줄어 성능이 향상됩니다.

02

주요 빌트인 Test

Distance, Trace, Dot, Pathfinding

UE5는 자주 사용되는 평가 기준을 빌트인 Test로 제공합니다. 이들을 조합하여 "적에게서 멀고, 시야가 차단되며, 접근 가능한 엄폐 위치"와 같은 복합 조건을 만들 수 있습니다.

C++// 1. Distance Test - 거리 기반 점수 // DistanceTo: 대상 Context // TestMode: Distance3D / Distance2D / DistanceZ // 활용: 적에게서 멀수록 점수 ↑ (InverseLinear) // 아군에게 가까울수록 점수 ↑ (Linear) // 2. Trace Test - 시선(LOS) 확인 // Context: Trace 대상 Context (예: EnemyActor) // TraceData: 채널, 형태, 확장 // TraceFromContext / TraceToContext // 활용: // - 적에게 보이지 않는 위치 (Filter: 실패만 통과) // - 적을 볼 수 있는 사격 위치 (Filter: 성공만 통과) // 3. Dot Test - 방향 기반 점수 // LineA: From → To (예: Querier → Item) // LineB: From → To (예: Querier → Enemy) // 결과: -1.0 ~ 1.0 (정면=1, 후방=-1) // 활용: AI 뒤쪽 위치 선호 (엄폐) // 적 전방 위치 선호 (대치) // 4. Pathfinding Test - 경로 비용 // TestMode: PathExist / PathCost / PathLength // Context: 경로 대상 // Filter: 경로가 존재하는 위치만 (PathExist) // Score: 경로가 짧을수록 점수 ↑ (InverseLinear) // 주의: 가장 비용이 큰 Test - 필터 후 실행 권장 // 5. GameplayTag Test - 태그 기반 필터 // TagsToMatch: 매칭할 태그 쿼리 // 활용: "Safe" 태그가 있는 위치만 선택 // 6. Project Test - NavMesh 투영 확인 // NavMesh 위에 있는 위치만 필터링
주의

Pathfinding Test는 각 아이템마다 경로 탐색을 수행하므로 가장 비용이 높습니다. 반드시 다른 Test로 충분히 필터링한 후 Pathfinding Test를 적용하세요.

03

EQS Context 시스템

쿼리의 기준점을 정의하는 Context

EQS Context는 Generator와 Test에서 사용하는 기준점입니다. 빌트인 Context(Querier, Enemy 등) 외에 커스텀 Context를 만들어 유연한 쿼리를 구성할 수 있습니다.

C++// 빌트인 Context // EnvQueryContext_Querier: 쿼리를 실행한 AI // EnvQueryContext_Item: 각 후보 아이템 자체 // 커스텀 Context: Blackboard의 타겟 액터 UCLASS() class UEnvQueryContext_TargetActor : public UEnvQueryContext { GENERATED_BODY() public: virtual void ProvideContext( FEnvQueryInstance& QueryInstance, FEnvQueryContextData& ContextData) const override { AAIController* Controller = Cast<AAIController>( QueryInstance.Owner.Get()); if (!Controller) return; UBlackboardComponent* BB = Controller->GetBlackboardComponent(); AActor* Target = Cast<AActor>( BB->GetValueAsObject(TEXT("TargetActor"))); if (Target) { // 단일 액터 Context UEnvQueryItemType_Actor::SetContextHelper( ContextData, Target); } } }; // 커스텀 Context: 근처 아군 목록 UCLASS() class UEnvQueryContext_NearbyAllies : public UEnvQueryContext { GENERATED_BODY() public: virtual void ProvideContext( FEnvQueryInstance& QueryInstance, FEnvQueryContextData& ContextData) const override { // 여러 액터를 Context로 제공 가능 TArray<AActor*> Allies; // ... 아군 검색 로직 ... UEnvQueryItemType_Actor::SetContextHelper( ContextData, Allies); } }; // Context를 여러 액터로 제공하면 // Test는 각 Context 액터에 대해 모두 평가 후 // 평균/최소/최대 등으로 집계한다
참고

Context가 여러 액터를 반환하면, Distance Test는 모든 Context까지의 거리 중 최솟값(또는 평균)을 사용합니다. "모든 아군에게서 가장 먼 위치"를 찾는 것도 가능합니다.

04

실전 EQS 쿼리 조합

엄폐 위치, 공격 위치, 후퇴 위치 찾기

실전에서는 여러 Generator와 Test를 조합하여 상황에 맞는 최적 위치를 찾습니다. 대표적인 패턴을 살펴봅니다.

C++// 패턴 1: 엄폐 위치 찾기 // Generator: SimpleGrid (AI 주변 격자) // Test 1: Trace to Enemy → Filter(실패만 통과) // → 적 시야에서 차단된 위치만 남김 // Test 2: Distance to Enemy → Score(InverseLinear) // → 적에게서 멀수록 높은 점수 // Test 3: Distance to Self → Score(Linear, Weight=0.5) // → 자신에게 가까운 위치 약간 선호 // Test 4: Pathfinding to Self → Filter(PathExist) // → 도달 가능한 위치만 // 패턴 2: 사격 위치 찾기 // Generator: OnCircle (적 주변 원) // Test 1: Trace to Enemy → Filter(성공만 통과) // → 적을 볼 수 있는 위치만 // Test 2: Distance to Enemy → Score(Range 500~1500) // → 적절한 교전 거리 // Test 3: Dot(Querier→Item, Querier→Enemy) → Score // → AI 전방에 있는 위치 선호 // 패턴 3: 후퇴 위치 찾기 // Generator: SimpleGrid (AI 주변) // Test 1: Distance to Enemy → Score(Linear) // → 적에게서 멀수록 높은 점수 // Test 2: Trace to Enemy → Score(InverseLinear) // → 시야 차단 위치 선호 (필수 아님) // Test 3: Distance to Allies → Score(InverseLinear, Weight=0.3) // → 아군 근처 약간 선호 // Test 4: Pathfinding → Filter(PathExist) + Score(InverseLinear) // → 빠르게 도달 가능한 위치

Test의 Weight를 조절하여 각 기준의 중요도를 세밀하게 제어하세요. 거리 Weight=1.0, 시야 차단 Weight=2.0으로 설정하면 엄폐를 더 중시하는 AI가 됩니다.

SUMMARY

핵심 요약

  • EQS Test는 Filter(제거)와 Score(점수) 두 가지 모드로 동작하며, Filter를 먼저 적용하는 것이 성능에 유리하다
  • Distance, Trace, Dot, Pathfinding이 핵심 빌트인 Test이며, Pathfinding이 가장 비용이 높다
  • 커스텀 Context로 Blackboard 값이나 동적 액터 목록을 쿼리 기준점으로 활용할 수 있다
  • Test의 Weight와 ScoringEquation을 조합하여 엄폐/공격/후퇴 등 다양한 전술 위치를 찾을 수 있다
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: 멀티 Test 쿼리 구성

Distance, Trace(Line of Sight), Dot(방향) 3가지 Test를 조합한 '엄폐 위치 찾기' EQS 쿼리를 구성하세요. 각 Test의 가중치를 조절하며 결과 변화를 관찰합니다.

실습 2: 커스텀 Context 구현

UEnvQueryContext를 상속하여 '가장 가까운 아군 NPC' 위치를 반환하는 커스텀 Context를 구현하세요. Distance Test에서 이 Context를 기준으로 아군 근처 위치를 평가합니다.

심화 과제

UEnvQueryTest를 상속하여 '해당 위치의 Navigation Cover 품질'을 평가하는 커스텀 Test를 구현하세요. NavMesh의 벽 근접도와 적으로부터의 Line of Sight 차단율을 복합 점수로 계산합니다.