This is more of a sanity check before I dig too deep.
Is it possible to run an EQS query via c++ in a standalone class? Or rather, is it safe/performant?
The EQSTestingPawn was my go-to for a working example, but I noticed a couple minor things about it that cause further questions.
The first is that the pawn calls RegisterExternalQuery on the query system, rather than asking it to run the query. Then, if I’m seeing it correctly, the pawn itself is stepping the query along manually until it finishes, then unregisters the external query. Was this built in just for testing purposes? Or is this the preferred way to interface with the query system outside of behavior trees?
Lastly, it looks like it would be perfectly safe to create an FEnvQueryRequest object, then call EQS->RunQuery(). If that were possible, we could just register the OnFinish callback of the query, send it off to the query system, and no longer have to manually step the query in our actor. This would be the preferred method!
I will begin messing around with it regardless, but I wanted to check in first to ensure there aren’t any dangerous pitfalls that I’m not aware of if we go this route.
EQSTestingPawn is purely debugging tool, the way it executes EQS queries is pretty much a hack to avoid dependency of EQS manager’s tick.
Regarding using EQS via C++ it’s fully supported, and that’s done by creating a
FEnvQueryRequest instance and calling
Execute on it.
Awesome, thanks for the info!
I have a follow up question: Are EQS tests capable of using async versions of physics functions?
I’ve done some testing with async traces and overlaps and they seem to work very well, but I’m not so sure it looks like it’s possible to use them in EQS tests.
My reasoning behind it is that the EQS system runs a test by simply calling a function that returns void. So it has no way of knowing whether the test is actually done performing. So it seems the test needs to perform all the work synchronously before it returns.
A potentially simple way to mitigate this would be to allow a test to return an enum for “running” and “finished”. That way a test could start up by performing an async request and return “running” until it receives the finished-callback.
In the context of the EQS system as a whole, it would still technically need to wait until it finished, but it would do so in a delayed processing sense, rather than stalling for a test to perform. It may or may not be beneficial, but I was curious whether you have looked into it, and whether you’ve made a conscious decision not to do so.
I see that it time-slices, but it wouldn’t handle the case in which the generation takes too long, or a single test takes too long. Perhaps it’s an unneeded negligible advantage to wait on an async test…just curious.
Thanks again for the help. Cheers!
Out of the box async tests are not really supported by EQS. But I can see how it could be done. Tests are being interrupted if they take too long, the logic for it is in the item iterator (a bit unfortunate placing, but works without requiring user to add any extra code). Implementing a async test would need to take advantage of the same mechanism iterator is using. Look how
bStepDone local variable gets set in FEnvQueryInstance::ExecuteOneStep.
One potential complication I can see (waste of perf really) is when there’s just one query running at given point - in such a case the query would repeatedly be asked to “continue” until time budget runs out. This should be easy to address.