Now Do Something
In Part 1, we setup an AI Behavior Tree for our enemy character, based on the state of a Boolean variable we called isChase. The variable was configured in AI Blackboard, and based on whether or not it was set to true, the character would perform different tasks. With the behavior tree ready to go, we will now setup the logic for the tasks the character will perform, as well as the logic to change the value of the isChase variable and thus, the characters state. When isChase is false, the default state, the enemy character will patrol the area. When isChase is true, the character will pursue the player.
Setting Up the Enemy Character
In the last post we created a new character by adding a new Blueprint Class based on the default Character class. We then set it to use the SK_Mannequin skeletal mesh and the ThirdPerson animation blueprint. We will need to add a few additional things to the character to make our task logic work properly. First we will add a new Boolean variable called isSprinting. Remember we called the enemy character AI_Patrol. Open the AI_Patrol blueprint by double-clicking it in the Content Browser. From the left pane select + sign next to Variables; a NewVar_0 variable will appear and its attributes will display in the right pane. Change the name to isSprinting and make sure the type is set to Boolean. We will use this variable to change the character's walk speed; normal walking pace when patrolling and running pace when chasing. Lastly click the small icon to the right of the variable to set it to public. You will know it is set when it looks like an opened eye, instead of a closed one.
Next we are going to give the character "vision", in a manner of speaking. From the top of the left pane select +Add Component, and in the search bar type Box Collision. Make sure you are in the Viewport tab, and you will see the new box appear in the Viewport. Name the box collision AI_Vision. This box will act as the enemy charcater's view and will detect the player character. Essentially, when the player character collides with this box, the enemy character can "see" the player. Move the AI_Vision box so that it does not intersect with the enemy character mesh or capsule component. I.E. move the box slightly in front of the character mesh. This will prevent and error in Unreal that occurs using this particular AI method. Now scale the box to give the enemy character a reasonable amount of vision. In my case I have the scale settings of the box set as follows:
X Scale: 8.5
Y Scale: 7.5
Z Scale: 1.0
I feel this gives the character a realistic amount of peripheral and forward vision. You may want to tweak this settings based on your particular game. If the scale is to short or narrow, the enemy character may never see the player, to large of a scale and it may see the player from a unrealistic distance. The collision box will not be visible during game play.
 |
| AI_Vision Collision Box |
Changing States
Now that we have the necessary variables and "vision" we will create the logic to change movement speed and the enemy character's state. In my case I want to character to move at a walking speed when patrolling to give it the illusion that it is carefully patrolling the area, and then when it sees the player character I want to run as it will be chasing the player.
Move to the Event Graph tab in the AI_Patrol blueprint. Right-click and add Event Tick. Next right-click and add a Branch. Connect Event Tick to Branch. We will branch based on the state of the isSprinting variable. From the left pane drag the isSprinting variable into the Event Graph. You will be presented with two options, Get or Set. In our case we want to Get the value the of the variable, so select Get. Connect it to the Condition node of the Branch.
Drag a new connector from the True node of the Branch and in the search box type Set Max Walk Speed; you may want to have Context Sensitive unchecked for this. Set the Max Walk Speed to your desired speed. This value is for when our enemy character is running. The default max speed for a third person player character is 600. So if you want the enemy to be faster than your character, set it higher than 600, lower if you want it slower. Now drag a new connector from the False node of the branch and again type Set Max Walk Speed in the search box. This time we are setting the speed for when the enemy character is walking. I have found that a speed of 150 aesthetically looks like a normal walking speed in game, but adjust as you see fit.
Lastly, right-click and add Get Character Movement to the event graph. Connect to the Target node on both Set Max Walk Speed events.
This will now set the walk speed of the enemy character based on the isSprinting variable. You may want to Comment the section for organizational purposes.
 |
| Walk Speed Logic |
We will need to create another set of logic for the enemy character for its vision. Again we are going to use the collision box we set up earlier to tell the enemy character when it "sees" the player character. In the left pane right-click on the collision box, remember will called it AI_Vision, and select Add Event and then choose OnComponentBeginOverlap. We are going to the set this to change the value of the isChase variable from Blackboard, and thus change the enemy character's state. Drag a connector from the top node of OnComponentBeginOverlap and type Blackboard Set Value as Bool and add it. Check the Bool Value box. This will set the value to true. Now we need to tell it what variable to change. Right-click and type Make Literal Name and add it. In the text box next to Value type isChase, the name of our Blackboard variable; this must match exactly. Connect Return Value to Key Name in the Set Value as Bool event.
Now we will create another event for when the player is out of the enemy character's vision. Again right-click the AI_Vision collision box in the left pane, select Add Event and this time choose OnComponentEndOverlap. Again we will add a Blackboard Set Value as Bool event and connect it the the top node of the OnComponentEndOverlap event. This time make sure that the Bool Value box is unchecked. Also connect the Key Name of this event to the Return Value of the Make Literal Name event.
Lastly we need to target both overlap events to the enemy character. Right-click and type Self in the search box and choose Get Reference to self. Drag a connector from Self and type Get Blackboard and select the Get Blackboard function. This will connect Self to the Target node of the Get Blackboard event. Finish by connecting the Return Value node of Get Blackboard to the Target Node of both Set Value as Bool events.
 |
| Vision and Character State Logic |
In a nutshell, if the player character overlaps the box collision of the enemy character, its changes the value of the isChase variable to true, which based on the AI Behavior tree will make the enemy character chase the player at running speed. When the player character does not overlap the collision box the enemy character sets the isChase variable to false and the enemy performs the patrol task at walking speed.
Setting Behavior
At this point all logic and necessary components have been added to the enemy character and it can change it's state based on the overlap condition of the collision box we created. We still need to tell the enemy character to use the Behavior Tree that we created in Part 1. To do this we will create a controller.
In the Content Browser click Add New, select Blueprints, Blueprint Class and in the search box type AIController and then select AIController from the results. Give it a descriptive name, in my case I called it AI_Cntrl. Open the blueprint for the new controller by double-clicking it in the Content Browser. We only need to setup some very simple logic.
In the Event Graph right-click, search and add Event BeginPlay. Drag a connector from Event BeginPlay and type Run Behavior Tree in the search box and select it. You will see that the Run Behavior Tree event automatically targets the built-in AIController. Lastly under the BTAsset option click Select Asset. As we have only set up a single Behavior Tree so far it should be the only option in the drop down. In our case we called ours AI_Behavior, so we select that one. I imagine in a game with multiple different enemy characters you may have multiple Behavior Trees. Thus just make sure you are selecting the appropriate one for the particular enemy character. That is all we need to tell the enemy character to use the Behavior Tree as soon as the level starts.
 |
| AI Behavior Tree Controller |
Tasks
Our next step is to create the logic for the patrol and chase tasks that the enemy character will perform. I will demonstrate these a little differently than I have before as I will show the blueprint first and then explain the logic behind it. We will start with the Chase task as it is a little simpler than the Patrol task.
First we need to create the tasks. In the Content Browser select Add New, Blueprints, Blueprint Class. From the search box type BTTask and select BTTAsk_BlueprintBase. Name the first one AI_Chase. Create a second BTTask_BlueprintBase class blueprint and name this one AI_Movement.
Chase Task
The AI_Chase task blueprint will only have an Event Graph. Open the blueprint by double-clicking it. See the figure below for the components.

The first component is Event Receive Execute. The Behavior Tree will initiate execution of the Chase task. We set the Execute task to send the desired task to the AI_Cntrl controller we set up earlier and connect them as shown. To add the Cast to AI_Cntrl node, right-click and type Cast to AI_Cntrl in the search box; works best with Context Sensitive unchecked. Next add the Get Controlled Pawn function and Cast to AI_Patrol and connect as shown. Thus far we are telling the task to be sent to the AI controller we created and then we are having that controller tell our AI_Patrol character to perform the task. Since we are chasing we want our enemy character to run. So we add a Set isSprting event by right-clicking and typing it in the search box. Check the isSprinting box. With this variable set to true our enemy character logic will change its walk speed to running speed. Finally we need to set a target for our enemy character to move to, in this case our Player Character. We accomplish this by adding a Simple Move to Actor function. Connect the Controller node to As AI_Cntrl in the Cast to AI_Cntrl node to tell it what controller to send its destination to, and then add and connect a Get Player Character node to the Goal of the Simple Move to Actor node. So the Simple Move function tells the controller, which controls our enemy character, to move to a destination, which in this case is the Player.
You may notice that the Get Player Character has an option for Player Index. This option, if I am not mistaken would be used primarily if your game has multiple player controlled characters, such as a multiplayer or co-op game. In this case we might set the index to a higher number to target a different player character. Since this game is single-player we can leave it at the default of 0.
Patrol Task
The AI_Movement patrol task uses much of the same logic as the chase task with a few exceptions. The exceptions are due to a delay I added before the enemy character moves to its next patrol point and the fact that the next patrol point is chosen at random from within a certain radius of the enemy character. The delay is purely for aesthetics.
As you can see most of the same base logic is used starting with Event Receive Execute which is initiate from the Behavior Tree, Cast To AI_Cntrl with Get Controlled Pawn and Cast to AI_Patrol and setting the isSprinting variable. I will focus on the extra logic for this task.
As I want to Enemy Character to pause before moving to the next patrol point, I have added a Delay function between Event Receive Execute and Cast to AI_Cntrl. I have the enemy pause for a random interval between zero and three seconds. To accomplish this I added a Random Float in Range option and set min value to zero and max to three and connect it to the Duration option of the Delay function. You could set the duration to a fix period of time, in which case you would not need to the Random Float in Range option. From there it connects through to Cast to AI_Cntrl.
The logic remains the same through Set isSprinting. Here I have the enemy character choose a random point within a radius of 3000 units from its current location. That random point will be set as the next patrol point it will move to. We are going to use the Blackboard variable Dest that we created in Part 1 to set the location.
From isSprinting add a Set Blackboard As Vector node. From the Key option drag a connector and then type Dest in the search box and select Get Dest Loc. From the Value option drag a connector and search for Get Random Reachable Point in Radius and select it. Set your desired radius in the Radius text box. We will need to tell it what the center point of the radius is, which in this case will be the current position of the enemy character. From the Origin option drag a connector and type GetActorLocation is the search box and select it. It will connect to the Return Value option. Then connect the Target option of GetActorLocation to OwnerActor from Event Receive Execute. Lastly connect Return Value of Get Random Reachable Point in Radius to the Value option of Set Blackboard Value as Vector. So the destination point is chosen from a random location with 3000 units of the enemy characters current location. Finally add a Finish Execute function at the end. We do this because the patrolling tasks is essentially a loop that the enemy character continues through while the isChase variable is false. Each time through the loop the character starts the task over choosing a new random point to move to.
Assign Tasks
Our final step in the whole process is to link the tasks to the Behavior Tree. Open the Behavior Tree blueprint by double-clicking it in the Content Browser; we called ours AI_Behavior.
Remember we have two Blackboard Based Condition Sequences. One for isChase Not Set and the other for isChase is Set. Right-click and expand Tasks from the pop-up menu. Select AI_Movemnent from the list. Connect this to the isChase is NotSet sequence. Right-click again and expand Tasks, this time select Move To. In the properties of Move To in the right pane make sure that the Blackboard Key option is set to Dest. Also connect this to to the isChase is NotSet sequence. Now our task for patrolling is set it the Behavior Tree.
Right-click, expand Tasks and select AI_Chase from the options. Connect this to the isChase is Set sequence. We do not have to add a Move To option to this sequence as the AI_Chase task sets the target itself.
Our AI behavior is now complete. When placed in the level our enemy character will have a default state of patrol, as isChase is initially set to false. When the level starts the enemy character will begin patrolling to random points. If at any point during the level the player character collides with the enemy's box collision, the enemy character's state changes to Chase, as the isChase variable is set to true, and it will begin chasing the character.
I have not yet added any logic to do anything if the enemy character catches the player. In an actual game catching the player would inflict damage or something along those lines. I may delve into that in a future post. The main focus of this series was to simply show how to program multiple behaviors into an AI character. As always I hope that you enjoyed this post and continue to check back in the future as I continue on my journey to become a game developer. Thanks for reading.
- End of Line