Initial AI Planning
To create our enemy AI, I wanted to create a pseudo flow chart that gives an abstract layout for how our AI will function. The logic for our AI will live in a Blueprint object called a Behavior Tree. The Behavior Tree lives in our AI Controller and tells the Enemy Character how to interpret certain gameplay event and how the AI should respond.
The process always starts at the root node at the top. The Behavior tree will always run the node that is furthest on the left. For example: Using the flow chart above, the tree starts at the root and moves down to the Selector. Selectors will look for the first node to run successfully, and will continue to run that node until it fails. The Selector will check the “Hunt Player (Power)” node first because it the leftmost node.
This node will first check the Game Mode object to see if the power is deactivated. If true, it will go down to the Sequence node. The Sequence node will run every node it can until one fails. It will then start from the beginning if the above checks continue to be true. The Sequence node will pick the leftmost node which is “Wait” in this senario. It will then run “Spawn around Player”, “Audio cue”, and finally “Run towards Player”.
If the Power was NOT deactivated, the Selector node would move onto check if the Radio or Computer objectives are deactivated. Finally, if non of the previous nodes are true, we “Turn invisible and teleport away from player”
Talking Unreal Engine Jargon
The Unreal Engine AI system uses odd names to describe different classes. I was able to learn a lot from this tutorial video posted on the official Unreal Engine YouTube channel. Here are some screenshots that I borrowed from that video:
Here are some key takeaways:
- Decorators are if statements. We can attach them to Selectors and Sequences. We can also define custom Decorators
- Tasks are actions performed by the AI. We can create custom tasks to do specific actions. Tasks have the potential to fail, affecting the AI’s behavior.
- The Blackboard is an object that is used for storing keys (variables). We use these keys to pass and store data to and from tasks. We can also use Decorators (if statements) against Blackboard keys.
Creating Custom Tasks
In order to make our AI do certain actions, I created some very basic custom Blueprint Tasks that we can implement in our Behavior Tree.
Here are the “Teleport AI” and “Get Player Actor” tasks
All of these tasks override the “Event Receive Execute AI” function. We use this function to run our logic when the AI performs the task. You can see above that the “Dest Location” Blackboard variable is passed from the Behavior Tree. We then teleport the AI using the Controlled Pawn reference. Finally, we run “Finish Execute”. It is important that we let the AI know that the task is finished executing because otherwise the task never ends. We can also return a boolean variable to tell the Behavior Tree if our custom task failed.
“Get Player Actor” returns a reference to our player character and stores it in the Blackboard. We can use the player reference later for teleporting to the player and making the AI walk toward them.
Creating Custom Decorators
I created a single custom decorator called “Check Objective Status”. This decorator accepts an Enumerator called EObjectiveType that has values for Power, Radio, and Computer.
You can see be basically do a switch statement on the passed Enumerator and return the boolean value we get from the Game Mode.
Creating the Behavior Tree
Here is the overview for our AI Behavior Tree:
You can zoom in on each node to see more detail. The title for each node is usually self-explanatory.
One node that likely stands out is the “Run EQS Query” node. This is a very special node that we use for querying the environment.
The Environment Query System
EQS is Unreal Engine’s experimental AI system that is used for navigating terrain. It allows the developer to create a series of points on terrain that are weighted according to desired properties such as distance, line of sight, etc. In my case, I am using EQS to find locations around the player for the AI to teleport to. Here is what my query looks like:
This system will try to find locations that are far from the player, but still within line of sight. I intend on adding fog later to make the AI harder to see. This is what the EQS looks like with the debug menu is turned on:
Without the debug menu:
Demo Time!
That’s it for this week. Next week I am thinking about adding sounds. I also need to add some more visual detail at some point.
Thanks for reading!