EQS test for ranking character visibility

Overview of my project:

I’m currently working on a “top down” style shooting game. It is possible to change your height (e.g., going up stairs) but the bullets always travel forward at the same Z; i.e., you can’t aim up and down. I am currently using, and am familiar with, EQS for the AI. I have a basic understanding of how to make C++ tests, but mostly only by refactoring existing ones. The project is primarily written with Blueprints.


One of the tests I would like to use involves, essentially, assessing how visible a character is. This breaks down into two parts:

1 - Will my gun height overlap with my enemy’s capsule?
2 - If so, what percent, roughly, of the character width is not blocked

I can solve the first part by making a custom modified from EnvQueryTest_Distance. The second part, I’m not so sure.

Right now I’m working on a modified version of EnvQueryTest_Trace. My basic plan is to use data binds to provide the bounds of the targets capsule, and do a bunch of traces across the width of the capsule if it is vertically aligned; then set true or false if enough of them match. I’m not quite sure how to reconcile this with the ANY/ALL filter, and I have no idea how to actually score it with a meaningful value.

The most pertinent code, I think, would be lines 81-91 of EnvQueryTest_Trace.cpp :

for (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It)
		const FVector ItemLocation = GetItemLocation(QueryInstance, It.GetIndex()) + FVector(0, 0, ItemZ);
		AActor* ItemActor = GetItemActor(QueryInstance, It.GetIndex());

		for (int32 ContextIndex = 0; ContextIndex < ContextLocations.Num(); ContextIndex++)
			const bool bHit = TraceFunc.Execute(ItemLocation, ContextLocations[ContextIndex], ItemActor, QueryInstance.World, TraceCollisionChannel, TraceParams, TraceExtent);
			It.SetScore(TestPurpose, FilterType, bHit, bWantsHit);

Which is essentially iterating over each context for each generated item and running the specified trace.

Pouring through the EQS code has definitely been quite the task. It’s one of those things where I flounder around completely lost until it clicks and I finally get how it all works together. I’m still floundering.

If anyone has a better or simpler solution, I’d love some feedback!