EQS Test와 Context
Distance, Trace, Dot, Pathfinding 테스트와 Context 시스템의 활용법을 마스터합니다
EQS Test 기본 구조
Test의 역할, Scoring, Filter 모드
EQS Test는 Generator가 생성한 각 아이템에 점수를 부여하거나 필터링합니다. 하나의 EQS 쿼리에 여러 Test를 조합하여 복합적인 평가 기준을 만들 수 있습니다.
// 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 계산 대상이 줄어 성능이 향상됩니다.
주요 빌트인 Test
Distance, Trace, Dot, Pathfinding
UE5는 자주 사용되는 평가 기준을 빌트인 Test로 제공합니다. 이들을 조합하여 "적에게서 멀고, 시야가 차단되며, 접근 가능한 엄폐 위치"와 같은 복합 조건을 만들 수 있습니다.
// 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를 적용하세요.
EQS Context 시스템
쿼리의 기준점을 정의하는 Context
EQS Context는 Generator와 Test에서 사용하는 기준점입니다. 빌트인 Context(Querier, Enemy 등) 외에 커스텀 Context를 만들어 유연한 쿼리를 구성할 수 있습니다.
// 빌트인 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까지의 거리 중 최솟값(또는 평균)을 사용합니다. "모든 아군에게서 가장 먼 위치"를 찾는 것도 가능합니다.
실전 EQS 쿼리 조합
엄폐 위치, 공격 위치, 후퇴 위치 찾기
실전에서는 여러 Generator와 Test를 조합하여 상황에 맞는 최적 위치를 찾습니다. 대표적인 패턴을 살펴봅니다.
// 패턴 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가 됩니다.
핵심 요약
- EQS Test는 Filter(제거)와 Score(점수) 두 가지 모드로 동작하며, Filter를 먼저 적용하는 것이 성능에 유리하다
- Distance, Trace, Dot, Pathfinding이 핵심 빌트인 Test이며, Pathfinding이 가장 비용이 높다
- 커스텀 Context로 Blackboard 값이나 동적 액터 목록을 쿼리 기준점으로 활용할 수 있다
- Test의 Weight와 ScoringEquation을 조합하여 엄폐/공격/후퇴 등 다양한 전술 위치를 찾을 수 있다
도전 과제
배운 내용을 직접 실습해보세요
Distance, Trace(Line of Sight), Dot(방향) 3가지 Test를 조합한 '엄폐 위치 찾기' EQS 쿼리를 구성하세요. 각 Test의 가중치를 조절하며 결과 변화를 관찰합니다.
UEnvQueryContext를 상속하여 '가장 가까운 아군 NPC' 위치를 반환하는 커스텀 Context를 구현하세요. Distance Test에서 이 Context를 기준으로 아군 근처 위치를 평가합니다.
UEnvQueryTest를 상속하여 '해당 위치의 Navigation Cover 품질'을 평가하는 커스텀 Test를 구현하세요. NavMesh의 벽 근접도와 적으로부터의 Line of Sight 차단율을 복합 점수로 계산합니다.