EQS: How to find the AI that is the closest to the player

Hello!

I’m trying to make it so that I can have a check to see what AI is the closest to the player. The reason for this is that I want to interact only with the closest AI. Currently when interacting, it gathers all the AIs within a set radius in the behavior tree, so it gets a little messy.

I have already set up the context:

Then I’m trying to set up the EQS. I tried to look at the official documentation, but I don’t quite understand how to use it in this instance. I also saw this post, which is where I got started on the context, but it lacked some information for me: AI: How to get the Closest Pawn using EQS for a Multiplayer Game?

I have a system set up like this at the moment:

But it doesnt look quite right? It seems like its getting hits of places that is in cover of the AI?

I could possibly do this too with just a service node in the behavior tree and check the condition with sequences that have the “blackboard based condition” attached to it, if that is easier to do. But from reading online, it seems like EQS is the best option for this.

All I’m trying to do, to recap, is to get the nearest AI, and based off of the hit, ONLY that AI can continue to a certain sequence. Every other AI should not be affected.

Thank you so much in advance!

You can use an actor generator, and choose the class of your AI:

Then run your query on your character like so:

The distance test:

1 Like

Is there a way to run the query in the behavior tree instead? And use it as a condition?

If you want to do it the other way around and run it on each of your AI, that becomes a bit of an issue, and also potentially a performance concern

This way wouldn’t work for that at least, I’ll have to think of how to make that work

Thats true! That might be a performance hit… I’m trying to get the AI to approach the character, and right now all the conditions that are needed to be passed are in the behavior system and the final task at the end of it is where its allowed to approach it…

There’s a run EQS node in behavior tree.
In your first image you have a context using GetAllActorsOfClass, you could perhaps run a sphere trace and return locations instead of it.

Well then if you want something working, you could run the EQS query on your character on a timer, and notify the selected AI by setting a boolean blackboard key. Just remember to set the previous AI to false when switching to a new one. Then perhaps consider adding a delay before restarting the query timer when an AI has been selected, to avoid issues with 2 AIs close to each other constantly being selected if you’re also moving

The issue is that every AI will run that EQS then, and that EQS is supposed to somehow return if a single AI should continue to part of its BT or not, while all the other AIs, that are also running the same EQS shouldn’t, which is not “easily” done in BT

EQS is used like that a lot in behavior tree, and it should only be executed when needed not every AI will be spamming it. You can take a look at the lyra project example, every AI is running an EQS to detect an enemy, and then after detecting an enemy another EQS is executed to control the movement while facing the enemy.

If the EQS is executed from time to time and only when needed then there’s no issue.

Yes, I know that EQS is used a lot in AI, but that’s not the point here. The point is that running an EQS on every AI to see if that specific AI is the closest AI to a player is probably the wrong approach, and is not easily done

I guess in that case I could use a distance check condition? and then run the check on what AI is the closest?

Now that I think about it, you could add an Object blackboard key on your BB, and make sure it’s Instance Synced. Then when you run the EQS on your character, set the value of that key to the selected AI. In your AI’s BT, have a Compare BB Entries check on the part of the tree that handles the behavior that should run when the AI is the closest one, and compare that key to SelfActor

Here’s an example from the Lyra project made by epic games, see here how a delay of 1 second is used with executing an EQS

Here’s 3 EQS used here with 0.5 second service

That still doesn’t help with the issue of OP at all :smiley:

Yes use a context that returns an array of locations, and in the EQS use a distance check, and any other filters like visibly.
You can control how the context generate these locations, maybe do a sphere trace, maybe the locations can be generated by perceived actors from perception component etc

OP wants to use the EQS in behavior tree and you’re against it.

OP wants a way to have the single closest AI among many react to the player. And at least from my experience, I can’t think of a nice way to do it using an EQS query on every AI in their BTs. If you on the other hand can think of a way then let us know

In that case I would do it in the player class itself, do some trace and inform nearby AI that the player is close, maybe setting a bool, this way you don’t need every AI to check for distance only the player does it once.

Okay but if I decide to go for only putting it in the behavior tree. I’m still not sure how I can run that check. Do I run the EQS. Set the blackboard key to a boolean value. Then run a condition on that value to see if it runs true or false?

Sorry, I’m quite new at this. Thank you both though for taking time to help! :slight_smile:

Something like this? Or is this completely wrong?

Because if I’m already running a check further up in the tree, that for example it only goes true if the AI is within the radius of 2000, and if thats true, then I run the EQS to see what the nearest AI is, then that shouldn’t be that much of a performance hit?

The AIs are animals in the forest, so its not to the same scale as a zombie game would be