Surroundings Question System (EQS) in C++ – Assume And Construct


I’m nonetheless working on the AI system for The Mirror’s Finish and I made a decision to maneuver the complete AI core from Habits Tree to Utility AI. Surroundings Question System (EQS) could be very properly built-in with Habits Bushes and I actually didn’t need to unfastened the power to run EQS from my customized AI system. Fortunately sufficient Unreal Engine lets us use EQS outdoors Habits Bushes in an easy approach. With this fast tutorial I’d like to indicate you easy methods to do it with C++.


The information varieties we’re excited about are UEnvQuery and FEnvQueryRequest.
The UEnvQuery class inherits from UDataAsset that, because the UE4 documentation states, is the “base class for a easy asset containing knowledge”.
The simplest option to setup this knowledge is to maintain a reference to an UEnvQuery in your Controller.

class AMyController : public AAIController

And fill it from the editor with an EQS asset beforehand created:

The FEnvQueryRequest is a struct that works as wrapper to permit question execution and in addition to move it info (question parameters).

You’ll name it immediately out of your class implementation (I truly choose to maintain a reference in my Controller to the question request , however it’s not wanted).


Out of your Controller you possibly can merely run the question via the FEnvQueryRequest this fashion:

FEnvQueryRequest HidingSpotQueryRequest = FEnvQueryRequest(FindHidingSpotEQS, GetPawn());

        EEnvQueryRunMode:: SingleResult, 

As first we initialize the question request passing the question we need to run (the reference to the EQS property beforehand outlined within the controller header) and the request proprietor, that on this case is the managed pawn.
When the request is initialized we’re able to execute it with the Execute perform.
The primary parameter defines easy methods to calculate the results of the question. We clearly have the identical choices obtainable from the BehaviorTree (SingleResult, RandomBest5Pct, RandomBest25Pct, AllMatching). The second parameter is the delegate object that may obtain question outcomes and the third is the delegate technique to make use of to deal with the outcome, this technique has to implement the FQueryFinishedSignature signature.


The delegate perform that we’ll designate to deal with the execution of the question is likely to be one thing like:

void HandleQueryResult(TSharedPtr outcome){
    if (result->IsSuccsessful()) {

The question result’s wrapped right into a FEnvQueryResult struct dealt with by a shared pointer (in just a few phrase, a wise pointer that personal the item it factors and delete it when no different references to the item can be found).
The FEnvQueryResult struct has some useful capabilities to confirm the question outcome. I’m utilizing isSuccessfull()however you might additionally use isFinished() and isAborted() to confirm different question states. As soon as you already know that the question is efficiently accomplished you possibly can entry question outcomes utilizing a perform like GetItemAsLocation(index) that may return a single merchandise coming from the question (Within the instance I’m asking for the merchandise at index 0) or you might ask for GetAllAsLocations() perform. For those who choose, and if it has sense for the question you have been working, you might additionally get the objects as Actors utilizing GetItemAsActorand GetAllAsActors. One other fascinating and helpful possibility is to retrieve all of the objects scores utilizing the GetItemScore perform:

for (int i = 0; i Gadgets.Num(); i++) 
    UE_LOG(LogTemp, Warning, TEXT("Rating for merchandise %d is %f"), i, result->GetItemScore(i));

Relying on what you have got outlined as question run mode (SingleResult, RandomBest5Pct, RandomBest25Pct, AllMatching) you would possibly get totally different scores however the objects shall be all the time ordered from highest to lowest rating.

Right here you could find the entire code instance, it’s also possible to discover a gist on GitHub .

Be at liberty to poke me on Twitter!

// AMyAIController.h ---------------------------------------------
#embrace "CoreMinimal.h"
#embrace "AIController.h"
#embrace "EnvironmentQuery/EnvQueryTypes.h"
#embrace "MyAIController.generated.h"

class UEnvQuery;

class EQSTUTORIAL_API AMyAIController : public AAIController


	UPROPERTY(EditAnywhere, Class = "AI")
	UEnvQuery *FindHidingSpotEQS;

	void FindHidingSpot();

	void MoveToQueryResult(TSharedPtr<FEnvQueryResult> outcome);

// AMyAIController.cpp ---------------------------------------------
#embrace "MyAIController.h"
#embrace "EnvironmentQuery/EnvQueryManager.h"

void AMyAIController::FindHidingSpot()
	FEnvQueryRequest HidingSpotQueryRequest = FEnvQueryRequest(FindHidingSpotEQS, GetPawn());
	HidingSpotQueryRequest.Execute(EEnvQueryRunMode::SingleResult, this, &AMyAIController::MoveToQueryResult);

void AMyAIController::MoveToQueryResult(TSharedPtr<FEnvQueryResult> outcome)
	if (result->IsSuccsessful()) {


Yari D'areglia

Yari D’areglia


Senior iOS developer @ Neato Robotics by day, sport developer and wannabe artist @ Black Robotic Video games by night time.



Leave a Comment