I was wondering if there was a way to wait for c++ function in another thread to complete before continuing execution. I am trying to use an EQS system through c++. It all works fine, but I would like the code after the FEnvQueryRequest.Execute call to wait until the Execute’s callback method is complete. Here is my code:
Query Functions:
void AEnemyAIController::FinishQuery(TSharedPtr<FEnvQueryResult> Result){
EQSResult = TSharedPtr<FEnvQueryResult>(Result);
TArray<FVector> Locations = TArray<FVector>();
TArray<float> Scores = TArray<float>();
for (int i = 0; i < EQSResult->Items.Num(); i++){
Locations.Add(EQSResult->GetItemAsLocation(i));
Scores.Add(EQSResult->GetItemScore(i));
}
FEnvQueryResMem NewMem = FEnvQueryResMem(Locations, Scores, EQSQueries.Num());
QueryFinished = true;
}
bool AEnemyAIController::RunEQS(AActor* QueryOwner, UEnvQuery* QueryTemplate, TArray<FEnvNamedValue> QueryParams, bool DebugDraw){
QueryFinished = false;
FEnvQueryRequest QueryRequest(QueryTemplate, QueryOwner);
QueryRequest.SetNamedParams(QueryParams);
FEnvQueryMemory MyMemory = FEnvQueryMemory(0);
int index = EQSQueries.Num() - 1;
MyMemory.RequestID = QueryRequest.Execute(EEnvQueryRunMode::AllMatching, this, &AEnemyAIController::FinishQuery);
FEnvQueryResMem Mem = EQSQueries[index];
TArray<FVector> Locations = Mem.Locations;
TArray<float> Scores = Mem.Scores;
for (int i = 0; i < Locations.Num(); i++){
if (Scores[i] > 0.6){
DrawDebugPoint(GetWorld(), Locations[i], 15, FColor::Black, false, 0.5);
}
print(FString::SanitizeFloat(Scores[i]));
}
if (DebugDraw){
}
const bool bValid = (MyMemory.RequestID >= 0);
if (bValid)
{
return true;
}
return false;
}
The Header File:
#pragma once
#include "AIController.h"
#include "EnvironmentQuery/Items/EnvQueryItemType.h"
#include "EnvironmentQuery/EnvQueryManager.h"
#include "EnvironmentQuery/EnvQuery.h"
#include "EnemyAIController.generated.h"
struct FEnvQueryMemory
{
/** Query request ID */
int32 RequestID;
FEnvQueryMemory(int32 ID){
RequestID = ID;
}
};
struct FEnvQueryResMem{
TArray<FVector> Locations;
TArray<float> Scores;
int32 index;
FEnvQueryResMem(TArray<FVector> InLocations, TArray<float> InScores, int32 InIndex){
Locations = TArray<FVector> (InLocations);
Scores = TArray<float>(InScores);
index = InIndex;
}
};
/**
*
*/
UCLASS()
class SCIFI_API AEnemyAIController : public AAIController
{
GENERATED_BODY()
void FinishQuery(TSharedPtr<FEnvQueryResult> Result);
TSharedPtr<FEnvQueryResult> EQSResult;
bool QueryFinished;
TArray<FEnvQueryResMem> EQSQueries;
public:
AEnemyAIController(const FObjectInitializer& Init);
UFUNCTION(BlueprintCallable, Category = "Enemy AI")
bool RunEQS(AActor* QueryOwner, UEnvQuery* QueryTemplate, TArray<FEnvNamedValue> QueryParams, bool DebugDraw);
};
Basically, what I want to do is RunEQS method, wait for FinishQuery to complete (which is called when QueryRequest.Execute is) before moving on! As a quick note, much of this code was duplicated from the BTTask_RunEQSQuery default class.
Thanks for the help!