AI Experiments with Unity 3D and Behavior Designer
Because three game projects is not enough to satisfy my inner creationist demon, I had ideas for two more games involving AI. After some failed starts, I got myself Behavior Designer, read up on behavior trees and here is what I got in about two hours of work.
If you are interested in behavior trees, or want to learn about Behavior Designer specifically, the below will satisfy your curiosity and even teach you a thing or two about building AI with Unity and Behavior Designer.
Obviously, those placeholder graphics are not there to impress anyone. So let’s break down the content of what you are seeing.
The basic setup of this game is a tower defense concept with a twist. The four small green blocks are meant to represent farms, or factories, or whatever. These are your gold producers. The big green block is a guardhouse. The grey blocks are just obstacles to test the pathfinding. The red disc is a spawner for enemy bandits.
The bandits are really simple at this point. They just want to plunder.
To the left is the behavior tree for the bandits.
Essentially, they repeat the simple sequence at the bottom forever.
Search is a complex action from the movement pack which essentially involves walking around randomly until you see a specified target, in this case any farm.
Seek then makes the bandit approach the farm using Unitys built-in navmesh pathfinding to move around obstacles, avoid other characters, etc.
The last step is a reference to an attack sequence that I will detail below.
This is a good example of a very simple, logical tree. Note that due to the repeat and sequence decorators, when the attack sequence is complete (i.e. the target is destroyed), the bandit will return to wandering and looking for the next target.
Everything you see the red capsules do in the video above is the result of this very simple tree.
Guardhouse and Guards
The guardhouse has a behavior tree as well, quite similar to the bandit tree above.
It also endlessly repeats a simple sequence: Check if you can see a bandit, if so spawn a guard, then wait for some seconds before you continue checking.
I could have easily written this simple behavior in code, but doing it in a tree makes it easy to expand it in the future.
The guards are the first entity with a more complicated behavior tree:
Let’s sum up first what the guard does: Search out the enemy, attack it and all other bandits nearby, then go back to the home base.
This is split into two branches. The first on the left runs two actions in parallel, completing whenever one of them succeeds.
The guard gets a seek target from the guardpost that spotted an enemy and moves towards it. While doing so (parallel selector) it also checks if it sees any bandits. If it does, it changes target to the bandit it spotted. Why? Because a guard should not run past one bandit to attack another one more far away.
Once it found its target, it will run a sequence until that fails. The only action in the sequence that can fail at all is the “Can See Object”, so this whole sequence continues until the guard cannot see any bandits. What it does is very simple: Spot a bandit, approach him, attack.
When the guard cannot see bandits anymore, it will return home to the guardpost. On the way home, it will ignore further bandits.
Both the guards and the bandits use the same external behavior tree to attack, which is why you see that reference in both their behaviors. This tree has some parameters that are different between them (guards attack slower but do more damage), but the behavior is the same:
Firstly, this whole sequence repeats until it fails, which it can only do if the target has gone away.
The “Can See Object” checks are there to make sure that all actions that require the target to exist are satisfied and to fail (and thus exit the tree) when the target has gone.
The NPC turns toward the target every tick, to make sure that even when the target is moving it won’t get out of sight so easily.
Next the selector and its subtree make sure that the NPC is in attack range. If the target is within range, the selector exits immediately and the sequence continues. If not, the next part runs and the NPC pursues the target until it is in range.
The next part is the actual attack, which for the moment is very simple, it simply sends a damage message to the target. Then the whole behavior pauses for a second or two to draw back the weapon, etc.
And with these trees, you get all that is visible in the video. Bandits seeking out farms and burning them down, guards hunting them down, all that. All built up from blocks of simple behavior modules.
It took me several attempts to get started on behavior trees, and having actual examples to follow was the best. The CTF and RTS examples included in Behavior Designer were a big help. Maybe this article will help someone else to also get started.