Right way of passing parameters to EQS after running it from "Run EQSQuery" node

Hello, I’m trying to figure out how to pass parameters to a EQS Query when I’m calling it from a behaviour tree task with the “Run EQSQuery” node. When I put a “Set Named Param” node right after the “Run EQSQuery” node UE freezes my whole computer when I run the game.

If I could store multiple locations generated by the EQS Query on a blackboard key (an array of vectors type variable would be needed but didn’t find how to make a BB key into an array) I could call the Query from the behaviour tree and simply tie the EQS Query parameter to a BB value instead of having to call a node from the BTTask blueprint. But I didn’t find a way to do this.

In the following link there are a screenshot of the BT, and one of the BTTask: https://imgur.com/a/O0tP4nv

Maybe I’m missing something obvious, but I don’t know. Any help would be welcome! And thanks in advance.

2 Likes

putting this here since is the 1st thread i found, and found nothing else to help.

i really really wish epic could improve this.

apparently there are two ways (at least).

  1. binding a property to a query param. then setting the query param on the behavior tree. this seems ideal but not all properties allows binding. (looking at you generate around actor).
  1. creating your own eqs context. which is poorly documented and very inflexible, hard to maintain, and potentially much slower.
    specially if you need/like to use blackboard values, which you should since that’s why the bb exists.
    you’ll probably have to do many sub-optimal casts.

since the instance of the context is not editable in the eqs window, you can’t really set properties. this means you’d need one class per specific value you wanna read and hard-code many stuff. :´(

this is the closest but it’s incomplete

how to get a bb value from the query

basically:

  • inherit from UEnvQueryContext
  • implement
virtual void ProvideContext(FEnvQueryInstance& QueryInstance, FEnvQueryContextData& ContextData) const override

then inside do


UObject* const QuerierObject = QueryInstance.Owner.Get();
AActor* ResultingActor = NULL;
// ----- your logic ---- 
// store the result only if it's a valid actor, otherwise the FEnvQueryContextData will think it succeeded 
// and proceed with the query
if (ResultingActor)
{
	UEnvQueryItemType_Actor::SetContextHelper(ContextData, ResultingActor);
}

in “your logic” you can do something like (please check for nulls or it might crash)

ACharacter* const QuerierActor = Cast<ACharacter>(QuerierObject);
AAIController* const contr = Cast<AAIController>(QuerierActor->GetController());
UBlackboardComponent* const bb = contr->GetBlackboardComponent();
UObject* const Object = bb->GetValueAsObject(KeyName); 
AActor* const TargetActor = Cast<AActor>(Object);
if (TargetActor) ResultingActor = TargetActor;
1 Like

It is worth adding that in in 5.4 you can create Blueprint based context provider for your EQS.

Create an instance of EnvQuertContext_BlueprintBase

Override function ProvideSingleLocation, where you can extract BB data from your querier actor.

And then you can place your newly created context blueprint into your EQS.