Environment Query System

An Environment Query is made up of several parts: 1

Generator

Produces the locations or Actors, referred to as Items, which will be tested and weighted by the Tests.

Contexts

Provides a frame of reference for the various Tests and Generators

Tests

Establishes how the Environment Query decides which Item from the Generator is the best option.

You may compare an EQS to a SQL Select query; generators are the parts of “select xx from table” and Tests are the “Where” part.

An Environment Query must be called from a Behavior Tree, and then it will use its Generator, reference its Contexts, and use its Tests to give the Behaviour Tree the highest weighted result.

Generators

Actors of Class

The Actors of Class Generator finds all the Actors of a given class within the specified Search Radius around the Search Center. The Actors returned are used as Items in Tests.

Custom Generators

In addition to the Generator types provided by the Engine, custom Generators can be implemented by inheriting from the EnvQueryGenerator_BlueprintBase class.

Note

Generators developed in C++ usually have better performance than in Blueprint.

Inside the custom Generator, there is a function that should be overridden called Do Item Generator.

Depending on the Context, the array may vary from a single entry containing the location of the Querier to the locations of every health pickup inside the Level.

The generated Actor and Vector are appended to the returned array by Add Generated Actor and Add Generated Vector respectively.

Points: Circle

The Points: Circle Generator radiates traces from the Circle Center, returning the hits on the edge of the radius (of the generated Circle) as Items.

Points: Cone

The Points: Cone radiates a trace from the Center Actor in the shape of a cone with the specified Cone Degrees as Items.

Points: Pathing Grid

Contexts

Contexts provide a frame of reference for any Tests or Generators used. A context can be as simple as the Querier (who is performing the Test) or more complex such as All Actors of a Type. A Generator, such as a Points: Grid, can use a Context that returns multiple locations or Actors. This will create a grid (of the defined size and density) at the location of each Context. In adition to Engine supplied Contexts, you can create custom Contexts in Blueprint with the EnvQueryContext_BlueprintBase class or through C++ code.

EnvQueryContext_BlueprintBase

You can create a custom Context through Blueprint using the EnvQueryContext_BlueprintBase class, which provides four functions that can be overridden, enabling to add custom Contexts for use within Tests in a query.

  • Provide Single Location

  • Provide Single Actor

  • Provide Locations Set

  • Provide Actors Set

Custome a Context in C++

Override ProvideContext() function and set context data by using UEnvQueryItemType::SetContextHelper().

void UEnvQueryContext_Player::ProvideContext(FEnvQueryInstance& QueryInstance, FEnvQueryContextData& ContextData) const
{
    AActor* QueryOwner = Cast<AActor>(QueryInstance.Owner.Get());

    //FVector Loc = QueryOwner->GetActorLocation();

    //FVector Loc = {-750,390,226};

    UWorld* World = QueryOwner->GetWorld();

    if(World != nullptr)
    {
        if(World->GetFirstPlayerController() != nullptr)
        {
            if(World->GetFirstPlayerController()->GetPawn() != nullptr)
            {
                FVector Loc = World->GetFirstPlayerController()->GetPawn()->GetActorLocation();
                UEnvQueryItemType_Point::SetContextHelper(ContextData, Loc);
            }
        }
    }
}

Tests

Within the Environment Query System (EQS), a Test can be performed to determine which Item produced from a Generator is the “best” option, given the Context (or frame of reference). There are several Tests that are provided with the Engine that cover a good percentage of use cases, such as “can an Item trace (see) another Location” or “is the distance between an Item and its Context within a specified range.” You can add multiple Tests to a Generator which can be an effective way to narrow down the result, given you the best possible option.

Note

If the Tests provided by the Engine can not meet your requirement, you can create custom Tests through C++ code.

Each Test has some unique properties to facilitate defining how the Test works.

Samples

I have created a sample project to demonstrate EQS usage in GitLab. 2

Footnotes

1

https://docs.unrealengine.com/4.26/en-US/InteractiveExperiences/ArtificialIntelligence/EQS/

2

https://gitlab.com/abenliao/eqs_ue