Environment Query System Quick Start Guide

This Quick Start will teach you the basics of using the Environment Query System. In it, you will use Environment Queries to find Actors and Locations, then, using a series of tests, you'll be given the best option. Then, using a Behavior tree, you'll have the AI flee from the Player Pawn (or Pawns) to a hiding spot.

This is a more advanced Quick Start and assumes you are familiar with Blueprints and Behavior Trees.

1 - Essential Setup

This Quick Start makes some assumptions about what is available in the project, as such, if you aren't comfortable making substitutions or problem solving on the fly, then you should setup the project as follows.

  1. Open Unreal Editor
  2. Generate a new project based on the Blueprint Top Down template Starter Content is optional for this quick start guide.

If you need further explanation of starting a new project, see the Project Browser User Guide.

2 - Enable the Environment Query System

The Environment Query System is considered Experimental, meaning it can change drastically at any time, so you must opt in to it.

  • As of 4.7 the Environment Querying System is enabled by going to Edit Menu > Editor Preferences > Experimental, and checking the check box next to Environment Querying System under the AI category.

This will eventually not be necessary, so if you don't see this check box, then you don't need to do this step.

3 - Create Nav Mesh Volume

The NavMesh in Unreal has a number of functions that work well with Behavior Trees, and while it may not be necessary depending on the game you are making, it will help in a number of game types. Also, the Top Down template already includes a Nav Mesh Bounds Volume, but you may choose to start in a completely blank project at a later date.

  1. Modes panel > Volumes > Volumes.
  2. Click and drag a Nav Mesh Bounds Volume into the map.

  3. Translate and Scale the volume so it encapsulates the areas you want your characters to be able to navigate.
    • You can use more than one Volume if you like, or one large one that encapsulates the entire level.
  4. While working in the Viewport, press the P key to see if your NavMesh is building.

    If you see a green mesh overlay on your floors, it is building correctly. When the mesh turns red, it means it is recalculating a section because you either moved the volume or the mesh inside of it. You can press the P key at any time to show or hide the NavMesh.

4 - Create the Basic Assets

To start, you will need create 7 assets in the Content Browser: An AI Controller Blueprint, A Character Blueprint, and Behavior Tree Asset, a Blackboard Asset, an EnvQueryContext_BlueprintBase (EQS Context) Blueprint, and 2 Environment Query templates. These are all the assets you will need to complete this Quick Start.

  1. New > Blueprint > AI Controller.
    You will need to search for AI Controller, as they are different from Player Controller.
     
    Name this Blueprint "Runner_AI_CON".
  2. New > Blueprint > Character.

    Name this Blueprint "AI_Character".
  3. New > Artificial Intelligence > Behavior Tree.
    Name the Behavior Tree "RunnerBT".
  4. New > Artificial Intelligence > Blackboard.
    Name the Blackboard "RunnerBlackboard".
  5. New > Artificial Intelligence > Environment Query.
    Name one Environment Query "FindHidingSpot".
  6. Name the other Environment Query "FindPlayer".
  7. New > Blueprint > EnvQueryContext_BlueprintBase.

    Name the Environment Query "PlayerContext".

5 - Character Blueprint

As we have created a project with a Character already in it, we have access to a humanoid Skeletal Mesh and its Animation Blueprint. We will use these in the tutorial, but feel free to use your own if you have them available.

This Character will become our new AI Character. The reason we use a Character, over say a Pawn, is to gain access to the Character Movement Component's functionality.

  1. Double-click the AI_Character Blueprint in the Content Browser to open it for editing.
  2. Select the Mesh component in the Components panel.
  3. In the Details panel, find the Mesh category and assign the SK_Mannequin (or your own) Skeletal Mesh.
  4. Move the Mesh Component to center it up inside in the capsule.
  5. Rotate the Mesh Component so it faces the direction the blue Arrow Component is pointing.
  6. In the Details panel, find the Animation category and assign the ThirdPerson_AnimBP to the Animation Blueprint Generated Class property.
  7. Select the CapsuleComponent from the Components panel, then in the Details panel, adjust the Capsule Half Height and Capsule Radius so they encompass the Skeletal Mesh.
  8. Select the Character Movement Component.
  9. In the Details panel, in the Movement Capabilities category, adjust the Nav Agent Radius and Nav Agent Height values.

    Set the Nav Agent Radius to at least the Capsule Radius, and the Nav Agent Height to at least twice the Capsule Half Height.
  10. With the Character Movement Component still selected, change the Max Walk Speed property, in the Character Movement: Walking category to 400.
  11. Click the Class Defaults    button and assign the new AI Controller (Runner_AI_CON) to the AIController Class property in the Pawn category.
  12. Compile and Save.

6 - Blackboard Setup

The Blackboard is the memory of the Behavior Tree. Here we will store a reference to the Actor we should flee from and a location to flee to.

  1. Double-click the Blackboard asset in the Content Browser.
  2. Using the New Key button , add a Vector key named FleeToLocation.
  3. Add an Object key named ActorToFleeFrom.

  4. Save your Blackboard asset.

7 - AI Controller Setup

The setup for this AI Controller is a single Run Behavior Tree node running our RunnerBT Behavior Tree when ever Event BeginPlay is executed.

  1. Double-click the Runner_AI_CON Blueprint in the Content Browser to open it for editing.
  2. In the Event Graph, have Event BeginPlay execute a Run Behavior Tree node using the RunnerBT as the BTAsset:

8 - Place the AI Character

We need to place our AI_Character into the level so it can interact with the player or environment.

  1. From the Content Browser, click and drag the AI_Character, that you created earlier, into the level.

9 - Behavior Tree Setup

Since you already have all the assets necessary to fill out the tree, you're going to be building this Behavior Tree:

Before we get into the steps to create this Behavior Tree, let's talk about what it does (or rather what it will do once we create the necessary EQS bits).

  • We enter the graph at the top Sequence Node, and then start executing it's children from left to right, and will keep executing as long as its children are successful.
  • First is the EQS Query node that runs the FindPlayer template. We only allow this node to execute once every 0.5 seconds, and if it fails, the tree is locked out of executing the other nodes by the Cooldown Node returning failed, thusly failing its parent sequence node.
  • But, if the EQS Query is successful (it finds the player), then the second EQS Query is allowed to execute, finding the AI a place to hide.
  • Finally we move to the place that the second EQS Query found.
  1. Double-click the RunnerBT Blueprint in the Content Browser to open it for editing.
  2. Add a Sequence Node (right-click in the Graph Area Composites Sequence)
  3. Connect the Root Node to this new Sequence Node
  4. Create a Run EQS Query Node (right-click in the Graph Area Tasks Run EQSQuery)
  5. Connect it to the Sequence Node
  6. Select this Run EQS Query Node, and in the Details panel, set the Query Template to FindPlayer
  7. While still in the Details panel set the Blackboard Key to ActorToFleeFrom
  8. Add a Cooldown Decorator to the Run EQS Query Node (right-click the Run EQS Query Node Add Decorator... Cooldown)
  9. Select the Cooldown Decorator and set its Cool Down Time to 0.5
  10. Create another Run EQS Query Node (right-click in the Graph Area Tasks Run EQSQuery)
  11. Select the second Run EQS Query Node, and in the Details panel, set the Query Template to FindHidingSpot
  12. Again, while still in the Details panel, set the Blackboard Key to FleeToLocation
  13. Position it to the right of the first Run EQS Query Node
  14. Create a Move To Node (right-click in the Graph Area Tasks Move To)
  15. Connect it to the Sequence Node
  16. Select the Move To node and set Blackboard Key to FleeToLocation
  17. While still in the Details Panel, set Acceptable Radius to 0.5
  18. Position it to the right of the second Run EQS Query Node

With everything connected the Behavior Tree will is ready and no further edits to it will be necessary.

10 - Creating the Player Context

While an Environment Query can generate a number of Items based on getting an Actor type, it doesn't do that for Contexts. So, we need a way to have the Player's Pawn as a Context, which is where the EnvQueryContext_BlueprintBase comes into play.

  1. Double click the PlayerContext Blueprint in the Content Browser to open it for editing.
  2. Override the ProvideActorsSet Function:
    The Override button is hidden until you mouse over the Functions portion of the My Blueprint panel. This will override the default behavior of the function with the Blueprint Graph that opens:
  3. Add a Get All Actors Of Class and connect it between the Provide Actor Set Node and the ReturnNode like this:
  4. Finally set the Actor Class of the Get All Actors Of Class Node to Top Down Character, Compile, and Save.

11 - Creating the FindPlayer EQS

This is the simpler of the two Environment Queries, as all it will do is return a list of all the TopDownCharacters within 1500 units of the AI then test if the AI can see the TopDownCharacters. If it can, then we'll get our ActorToFleeFrom for our Behavior Tree.

There are a number of ways this process can be done, each with their own advantages and disadvantages. Using EQS for this means that we can add additional tests at a later time to choose the best enemy (TopDownCharacter) to run from.

Some quick glossary terms you're going to run into:

  • A Generator creates Items in relation to a Context
  • Items are used in Tests often in relation to a Context (how far is Item X from Context Y)
  • Items are culled or scored based on the results of Tests
  1. To start, double click the FindPlayer Environment Query asset in the Content Browser.

    Which will open the Environment Query editor which will look like this:

    The Environment Query editor works almost exactly like the Behavior Tree editor.
  2. Right-click into the Update Graph area, and select ActorsOfClass from the Context menu:

    Which will create the ActorsOfClass Generator like so:
  3. To connect nodes in the Environment Query editor, you just need to drag from the bottom of the Root node to the Top of the ActorsOfClass node, exactly how it is done in the Behavior Tree editor.

    There can only be one Generator per Environment Query
  4. Next, setup the ActorsOfClass node by selecting it, and changing its Search Radius and Searched Actor Class properties:
    • Search Radius = 1500
    • Searched Actor Class = TopDownCharacter.
    This Generator finds all the Actors of the given Class, within the radius, and creates Items from them.
  5. Add a Trace test to the ActorsOfClass node

    Trace tests are useful to check if a Context has line of sight to an Item, in this case, our AI to the Items (TopDownCharacters/Players in this case)
  6. Now select the Trace Test on the ActorsOfClass node by left-clicking it, and in the Details Panel, change the Bool Match Property to false (unchecked)

And that's it!

12 - Creating the FindHidingSpot EQS

For this step you'll be creating a much more involved Environment Query. It's going to create a grid of points, projected onto the NavMesh, then run a series of tests to figure out the best place to hide. Some of the tests will simply cull out completely unsatisfactory locations, such as those that are visible to the Player's Character (Trace), others will weight the potential hiding spots based on if they are reachable on the NavMesh (PathFinding) or how much a point is in front of the Player's Character (Dot Product).

Just a quick reminder:

  • A Generator creates Items in relation to a Context
  • Items are used in Tests often in relation to a Context (how far is Item X from Context Y)
  • Items are culled or scored based on the results of Tests
  1. To start, Double-click the FindHidingSpot Environment Query asset in the Content Browser.
  2. Create Simple Grid Generator and connect it to the Root node
  3. Select the Simple Grid Generator and in the Details Panel set the following Properties:
    • Grid Size = 2000.0
    • Space Between = 150.0
    • Navigation Filer = RecastFilter_UseDefaultArea
    • Project Down = 2048.0
    • Post Projection Vertical Offset = 32.0
    These settings for the Grid Generator will create a sizable, but manageable, number of Items for the Query to test against. The Project Down, Project Up, and Post Projection Vertical Offset properties are particularly useful to change if you have an AI that needs to find something above or below them.
  4. Add 2 Distance Tests by Right-clicking the Simple Grid node and selecting Tests Distance
  5. Select the first one and in the Details panel adjust the following properties:
    • Distance To = Player Context
    • Test Purpose = Score Only
    This Distance test is meant to give Items further from the Player a higher Score.
  6. Select the second one and in the Details Panel adjust the following Properties:
    • Test Purpose = Score Only
    • Scoring Equation = Inverse Linear
    • Scoring Factor = 2.0
    This Distance test is meant to give Items closer to the AI a higher Score, and this test carries more weight than the previous Distance Test meaning it will favor closer to the AI but still select away from the Player.
  7. Add 2 Trace Tests by Right-clicking the Simple Grid node and selecting Tests Trace
  8. Select the one of the Trace tests and in the Details panel change Context to PlayerContext (the Context created earlier in this Quick Start):

    Here we remove any Item that the Player Pawn or AI pawn has line of sight to. Also, you may be concerned that this test comes after a bunch of Distance tests, but it's ok, as the Environment Query runs Trace tests first regardless of order here. Also, the other Trace requires no additional setup.
  9. Add a Dot test by Right-clicking the Simple Grid node and selecting Tests Dot
  10. Select the Dot test and in the Details panel adjust the following properties:
    • Line A - Rotation = PlayerContext
    • Line B - Line From = PlayerContext
    • Absolute Value = True
    • Test Purpose = Score Only
    • Scoring Factor = -1.0
    Here things get tricky, at the high level, this is saying "Favor Items that are to the sides of the Player Pawn," but how it works is a bit odd. A Dot Product function will return how alike two vectors are on a scale of 1.0 (perfectly the same) to -1.0 (completely opposite). So if we get the Absolute Value of the Dot Product between the rotation vector of the Player and the vector from the Player to the Item we'll favor points in front of and behind the Player. But if we set the Scoring Factor to -1.0, then we favor to the sides of the Player.
  11. Add a PathFinding test by Right-clicking the Simple Grid node and selecting Tests PathFinding
  12. Select the PathFinding test and in the Details panel adjust Test Purpose to Score Only:

    That's it for the editing! The final Environment Query will look similar to this:

13 - Play in Editor and Testing

Now since you setup the Behavior Tree earlier, and told the AI Controller to run it, you are ready to test!

  • Hit the Play in Editor button and watch your AI flee from you.

14 - Next Steps

This page covers a number of ideas for improvements you can make now that you're familiar with the basics of the Environment Query System.

Ideas

  • TopDownCharacter is far too specific, update everything to a more flexible system.

  • The Behavior Tree shows one way to set a system like this up:

    • Try using a Wait node instead of the Cooldown Decorator. This will require a Bool Blackboard entry and some extra work in the AI Controller.

    • Add a secondary Behavior that, after a time, the AI will begin to wander around.

    • Bonus - Store the last known location(s) of the Player(s) and use those in an Environment Query to find a better hiding spot.

    • Double Bonus - Have the AI attempt to approach a Player from behind without entering the forward view arc of the Player(s).

  • Did you know you can create your own Generators in Blueprint? Maybe there's a better way to find the possible points for the AI to hide.

  • The ' key (single quote) turns on a host of Gameplay Debugging tools. Check out all of the options available in the Editor Preferences > Gameplay Debugger