Artificial intelligence

AI is a decision-making process that adds NPCs in a game. AI is a programmable decision-making process for NPCs to govern their responses and behaviors in a game. A game character that is not controlled by a human player has no form of intelligence, and when these characters need to have a higher form of decision-making process, we apply AI to them.

AI in games has progressed tremendously over the years and NPCs can be programmed to behave in a certain way, sometimes, with some form of randomness, making it almost unpredictable so that players do not have a simple, straightforward strategy to win the level.

The decision-making process, which is also the logic of the NPCs, is stored in a data structure known as a Behavior Tree. We will first learn how to design a simple Behavior Tree then learn how to implement this in Unreal Engine 4.

Understanding a Behavior Tree

Learning how to design a good decision-making tree is very important. This is the foundation on which programmers or scripters rely to create the behavior of a character in a game. The Behavior Tree is the equivalent of a construction blueprint for architects who design your house.

A Behavior Tree has roots that branch out into layers of child nodes, which are ordered from left to right (this means that you always start from the left-most node when traversing the child nodes) that describe the decision-making process. The nodes that make up the Behavior Tree mainly fall into three categories: Composite, Decorator, or Leaf. Once you are familiar with a couple of the common types of nodes in each of the three categories, you would be ready to create your own complex behaviors:

 

Composite

Decorator

Leaf

Children nodes

Having one or more children are possible.

This can only have a single child node.

This cannot have any children at all.

Function

Children nodes are processed, depending on the particular type of composite node.

This either transforms results from a child node's status, terminates the child, or repeats the processing of the child, depending on the particular type of Decorator.

This executes specific game actions/tasks or tests.

Node examples

The Sequence node processes the children nodes from the left-most child in sequence, collects results from each child, and passes the overall success or failure result over to the parent (note that even when only one child fails and the rest succeed, the overall result is failure). This can be thought of as an AND node.

The Inverter node converts a success to a failure and pass this inverted result back to the parent. It works vice versa as well.

The Shoot Once leaf node shows that the NPC would shoot once and return a success or failure, depending on the result.

Exercise – designing the logic of a Behavior Tree

This is a simple walkthrough of how a Behavior Tree can be constructed. The following legend will help you identify the different components of a Behavior Tree:

Exercise – designing the logic of a Behavior Tree

Example – creating a simple Behavior Tree

The following figure shows a simple response for an enemy NPC. The enemy will only start attacking when the war starts.

Example – creating a simple Behavior Tree

The following figure has been expanded on the earlier Behavior Tree. It gives a more detailed description of how the enemy NPC should approach the target. The NPC will run towards the target (the player character in this case), and if it is close enough, it starts shooting the player.

Example – creating a simple Behavior Tree

Next, we set more behaviors that show how the NPC will shoot the player. We give the enemy NPC a little intelligence: hide if someone is shooting at it and start shooting if no one is shooting at it; if the player starts moving in toward it, the NPC starts moving backward to a better spot or goes for a death match (it shoots the player at close range).

Example – creating a simple Behavior Tree

How to implement a Behavior Tree in Unreal Engine 4

The Unreal Editor allows complex Behavior Trees to be designed using the visual scripting Blueprints together with several AI components.

There is also an option in Unreal Engine 4 where very complex AI behaviors can be programmed in the conventional way or in combination with Blueprint visual scripting.

The nodes for BT in UE4 are broadly divided into five categories. Just to recap, we have already learned a little about the first four in the previous section; Service is the only new category here:

  • Root: The starting node for a Behavior Tree and every Behavior Tree has only one root.
  • Composite: These are the nodes that define the root of a branch and the base rules for how this branch is executed.
  • Decorator: This is also known as a conditional. These attach themselves to another node and make decisions on whether or not a branch in the tree, or even a single node, can be executed.
  • Task: This is also known as a Leaf in a typical BT. These are the leaves of the tree, that is, the nodes that "do" things.
  • Service: These are attachments to composite nodes. They are executed at a defined frequency, as long as their branch is being executed. These are often used to make checks and update the Blackboard. These take the place of traditional parallel nodes in other Behavior Tree systems.

Navigation Mesh

For AI characters to move around in the game level, we need to specifically tell the AI character which areas in the map are accessible.

Unreal Engine has implemented a mesh-like component known as Navigation Mesh. The Navigation Mesh is pretty much like a block volume; you could scale the size of the mesh to cover a specific area in the game level that an AI character can move around in. This limits the area in which an AI can go and makes the movement of the character more predictable.

Tutorial – creating a Navigation Mesh

Go to Modes | Volumes. Click and drop Nav Mesh Bounds Volume into your game level. The following screenshot shows where you can find Nav Mesh Bounds Volume in the editor:

Tutorial – creating a Navigation Mesh

If you are unable to see Nav Mesh Bounds Volume in your map, go to the Show settings within the editor, as shown in the following screenshot. Make sure the checkbox next to Navigation is checked:

Tutorial – creating a Navigation Mesh

Scale and move the Navigation Mesh to cover the area of the floor you want the AI character to be able to access. What I have done in the following screenshot is to scale the mesh to fit the floor area which I want my AI character to walk in. Translate the mesh upward and downward to allow it to be slightly above the actual ground mesh. The Navigation Mesh should sort of enclose the ground mesh. This screenshot shows how the mesh looks when it is visible:

Tutorial – creating a Navigation Mesh

Tutorial – setting up AI logic

Here's an overview of the components that we will create for this tutorial:

  • Blueprint AIController (MyNPC_AIController)
  • Blueprint Character (MyNPC_Character)
  • BlackBoard (MyNPC_Brain)
  • Behavior Tree (MyNPC_BT)
  • Blueprint Behavior Tree Task (Task_PickTargetLocation)

The important takeaway from this tutorial is to learn how the components are linked up to work together to create logic; we make use of this logic to control the behavior of the NPC.

In terms of file structure in Content Browser for these different file types, you can group the different components into different folders. For this example, since we are only creating one NPC character with logic, I will put all these components into a single folder for simplicity. I created MyFolder under the main directory for this purpose.

We start creating the AI logic of our NPC starting with AIController and Character. The Character Blueprint is the object that contains the link to the mesh, and we will drag and drop this Character Blueprint into the level map after we make some initial configurations. The AIController is the component that gives the NPC character its logic.

We will discuss the rest of the other three components as we go along.

Creating the Blueprint AIController

Go to Create | Blueprint. Type in AIController into the textbox to filter by class, as shown in the following screenshot. Select AIController as the parent class.

Rename this AIController Blueprint as MyNPC_AIController:

Creating the Blueprint AIController

We will come back to configure this later.

Creating the Blueprint character

Go to Create | Blueprint, and type in Character in the textbox to filter by class. Select Character as the parent class for the Blueprint, as shown in the following screenshot. Rename this Blueprint as MyNPC_Character.

Creating the Blueprint character

Adding and configuring Mesh to a Character Blueprint

Double-click on MyNPC_Character in Content Browser to open the Character Blueprint editor. Go to the Components tab.

In the Perspective space view, you will see an empty wireframe-capsule-shaped object, as shown in the following screenshot. In the Details panel in the Blueprint editor, scroll to the Mesh section, and we will add a mesh to this Blueprint by selecting an existing mesh we have. You can go to Content Browser, select HeroTPP, and click on the arrow next to it. Alternatively, you can click on the search button next to the box and find HeroTPP:

Adding and configuring Mesh to a Character Blueprint

After selecting HeroTPP as the skeletal mesh, you will see the mesh appearing in the wireframe capsule. Notice that the HeroTPP skeletal mesh is much larger than the capsule wireframe, as shown in the following screenshot. We want to be able to adjust the size of the wireframe to surround the height and width of the skeletal mesh as closely as possible. This will define the collision volume of the character.

Adding and configuring Mesh to a Character Blueprint

This figure shows when the wireframe for the skeletal mesh is the correct height:

Adding and configuring Mesh to a Character Blueprint

Linking AIController to the Character Blueprint

Go to the Default tab of MyNPC_Character, scroll to the AI section, and click on the scroll box to display the options available for AIControllers. Select MyNPC_AIController to assign the character to use this AIController, as shown in this screenshot. Compile, save, and close MyNPC_Character for now.

Linking AIController to the Character Blueprint

Go to Content Browser, and click and drop MyNPC_Character into the level map. Compile and play the level. You will see that the character appears in the level but it is static.

Adding basic animation

Similar to the early implementation of assigning an animation to the mesh, we will add animation to MyNPC_Character. Double-click on MyNPC_Character to open the editor. Go the Default tab, scroll to the Animation section, and assign the Animation Blueprint (MyNPC_Blueprint), which we created earlier for this Character Blueprint. The following screenshot shows how we can assign animation to the character. Compile and save MyNPC_Character:

Adding basic animation

Now, play the level again, and you will see that the character is now walking on the spot (as we have set the speed to 100 in the Animation Blueprint, MyNPC_Blueprint).

Configuring AIController

Go to Content Browser. Then, go to MyFolder and double-click on MyNPC_AIController to open the editor. We will now add nodes in EventGraph to design the logic.

Our first mission is to get the character to move forward (instead of just walking on the same spot).

Nodes to add in EventGraph

The following are the nodes to be added in EventGraph:

  • Event Tick: This is used to trigger the loop to run at every tick
  • Get Controlled Pawn: This returns the pawn of AIController (which will be the pawn of HeroTPP)
  • Get Actor Forward Vector: This gets the forward vector
  • Add Movement Input: This links the target to Get Controlled Pawn and Link World Direction to the output of Get Actor Forward Vector
  • IsValid: This is to ensure that the pawn exists first before actually changing the pawn values

The following screenshot shows the final EventGraph that we want to create:

Nodes to add in EventGraph

Now, play the level again, and you will see that the character is now walking forward. But it's doing this a little too quickly. We want to adjust the maximum speed at which the character moves.

Adjusting movement speed

Double-click on MyNPC_Character to open the editor. Go to the Default tab, scroll to the Character Movement section, and set Max Walk Speed to 100, as shown in this screenshot:

Adjusting movement speed

Creating the BlackBoardData

BlackBoardData functions as the memory unit of the brain of the NPC. This is where you store and retrieve data that would be used to control the behavior of the NPC. Go to Content Browser, and navigate to Create | Miscellaneous | Blackboard. Rename it MyNPC_Brain.

Creating the BlackBoardData

Adding a variable into BlackBoardData

Double-click on MyNPC_Brain to open the BlackBoardData editor. Click on New Key, select Key Type as Vector, and name it TargetLocation. This screenshot shows that TargetLocation is created correctly. Save and close the editor.

Adding a variable into BlackBoardData

Creating a Behavior Tree

Behavior Tree is the logic path that NPC goes through to determine what course of action to take.

To create a Behavior Tree in Unreal Engine, go to Content Browser | Create | Miscellaneous, and then click on Behavior Tree. Rename it MyNPC_BT.

Creating a Behavior Tree

Double-click on MyNPC_BT to open the Behavior Tree editor. The following screenshot shows the setting that we want for MyNPC_BT. It should have MyNPC_Brain set as the BlackBoard asset. If it doesn't, search for MyNPC_Brain and assign it as the BlackBoard asset.

If you have already gone through the earlier exercise and are familiar with a Behavior Tree, you will notice that in this editor that there is a Root node, which you could use to start building out your NPC's behavior.

Creating a Behavior Tree

Creating a simple BT using a Wait task

The next step here is to add on a composite node (either Sequence, Selector, or Simple Parallel). In this example, we will select and use a Sequence node to extend our Behavior Tree here. You can click and drag from the Root node to open up the contextual menu, as shown in the following screenshot. Alternatively, just right-click to open up the menu and select the node that you want to create.

Creating a simple BT using a Wait task

We will add a Wait task from the Sequence node. Click and drag to create a new connection from the Sequence node. From the contextual menu, select Wait. Set Wait to be 15.0s, as shown in this screenshot. Save and compile MyNPC_BT.

Creating a simple BT using a Wait task

After compiling, click on Play in the Behavior Tree editor. You would see the light moving through the links and especially from the Sequence node to the Wait task for 15s.

Using the Behavior Tree

Now that we have a simple implementation of the Behavior Tree, we want our NPC character to start using it. How do we do this? Go to Content Browser | MyFolder, and double-click on MyNPC_AIController to open up the editor. Go to the EventGraph tab where we initially created a simple move forward implementation. Break the initial links between the IsValid node and Add Movement Input. Rewire them based on the following screenshot by linking the IsValid node to a new Run Behavior Tree node. In the Run Behavior Tree node, assign BTAsset to MyNPC_BT. Next, replace Event Tick with Event Begin Play (since the BT will now replace the thinking function here). Save and compile.

Using the Behavior Tree

Creating a custom task for the Behavior Tree

We want to now make the NPC select a location on the map and walk toward it.

This requires the creation of a custom task where the NPC has to select a target location. We have already created an entry in the BlackBoardData to store a vector value. However, we have not made a way to assign values to the data yet. This would be done by creating a custom Behavior Tree task.

Go to Content Browser | Create | Blueprint. For the parent class, search for BTNode and select BTTask_BlueprintBase, as shown in the following screenshot. Rename this task as Task_PickTargetLocation.

Creating a custom task for the Behavior Tree

Double-click on the newly created Task_PickTargetLocation. Go to EventGraph, create the following nodes, and link these nodes:

  • Event Receive Execute: Link Owner Actor to the target of Get Actor Location. When PickTargetLocation is executed, Event Receive Execute starts.
  • Get Actor Location: Link Return Value to Origin of Get Random Point in the Radius node.
  • Set Blackboard Value as Vector: Link Event Receive Execute to the execution arrow of Set Blackboard Value as Vector.
  • Get Random Point in Radius: Link Return Value to the Value input for Set Blackboard Value as Vector.
  • Finish Execute: Link Set Blackboard Value as Vector to the input execution of Finish Execute.
    Creating a custom task for the Behavior Tree

Notice that there is a New Target Loc variable linked to Key of Set Blackboard Value as Vector. We need to create a new variable for this. Click on +Variable, as shown in the following screenshot, to create a new variable. Name the new variable New Target Loc.

Creating a custom task for the Behavior Tree

Click on the newly created New Target Loc to display the details of the variable. Select BlackBoardKeySelector as the variable type, as shown in this screenshot:

Creating a custom task for the Behavior Tree

Save and compile the custom task.

Using the PickTargetLocation custom task in BT

Add a new link from the current Sequence composite node. Place the Task_PickTargetLocation node to the left of the Sequence node so that it would be executed first, as shown in the following screenshot. Make sure that New Target Loc is set as TargetLocation:

Using the PickTargetLocation custom task in BT

Replacing the Wait task with Move To

Delete the Wait node, and add the Move To node in its place. Make sure that Blackboard Key for Move To is set as TargetLocation, as show in this screenshot:

Replacing the Wait task with Move To

After compiling, click on Play to run the game. Double-click on MyNPC_BT to open the Behavior Tree editor. You would see the light moving through the links and the TargetLocation value changing in the Blackboard, as shown in this screenshot:

Replacing the Wait task with Move To

Remember to go back to the map level and see how the NPC is behaving now. The NPC now selects a target location and then move to the target location. Then, it selects a new target location and moves to another spot.

With this example, you have gained a detailed understanding of how to set up AI behavior and getting AI to work in your level. Challenge yourself to create more complex behaviors using the knowledge gained in this section.

Implementing AI in games

I am sure you have noticed that we definitely need to create more complex behaviors to make a game interesting. In terms of implementation, it is often easier to implement more complex AI through a combination of programming and use the editor functions to take this a step further. So, it is important to know how AI can be triggered via the editor and how you can customize AI for your game.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset