Creating Basic Artificial Intelligence

Lee Zhi Eng

December 2015

In this article by Lee Zhi Eng, the author of the book, Building a Game with Unity and Blender, we will learn how to create basic game AI in Unity!

In a nutshell, artificial intelligence is all about making decisions autonomously based on a set of conditions and requirements. If a given condition has been met, then the AI will try to move from its current state to the other state that fits the criteria. This is what we call the finite state machine.

(For more resources related to this topic, see here.)

In order to know what conditions we need to set in our AI and what are the decisions that it can make, we will design yet another flow chart for the AI:

In this article, we will only focus on the part where the AI will start chasing the player whenever the player is nearby.

Before we start writing the code, we need to add a component called Nav Mesh Agent to our monster prefab. Without this component, our monster will lose the ability to find the shortest path and move toward the player.

After that, we will create a C# script called EnemyAI and attach it to our monster prefab. We will start writing the code by declaring the variables needed by the script:

public NavMeshAgent agent;
public float healthPoint = 50;
public Animator animator;
GameObject player;

Then, in the Start() function, we will find the player by calling GameObject.FindWithTag(), and save it to the player variable. Since there is only one player in the entire scene, it's OK to search through the entire scene to find the player when the game starts. Do not, however, use this function in the Update() function because that will greatly slow down the performance of the game.

After that, in the Update() function, we will calculate the distance between the monster and the player character. If the player is nearby, then the monster will start chasing him by calling the SetDestination() function from the Nav Mesh Agent.

void Update ()
{
..if (player != null)
..{
....// Check if player is nearby
....if (Vector3.Distance(transform.position,
     player.transform.position) <= 6)
....{
......// Move toward player
......agent.SetDestination(player.transform.position);
......// Pass the movement velocity to animator
......animator.SetFloat("runningSpeed", agent.velocity.magnitude);
....}
..}
}

Finally, we also create the GetDamage() function that was used previously in the melee attack script so that the Unity compiler will no longer display an error that says the GetDamage() function not found. In this function, we will deduct the health points of the monster and check if the health point has reached zero. If it does, it will be removed from the scene by calling the Destroy() function:

public void GetDamage (float damage)
{
..healthPoint -= damage;
..if (healthPoint <= 0)
..{
....Die ();
..}
}
void Die ()
{
..Destroy (gameObject);
}

The following is the full code for the artificial intelligence:

using UnityEngine;
using System.Collections;

public class EnemyAI : MonoBehaviour
{
..public NavMeshAgent agent;
..public float healthPoint = 50;
..public Animator animator;
..GameObject player;
..void Start ()
..{
....// Find player
....player = GameObject.FindWithTag ("Player");
..}
void Update ()
..{
....if (player != null)
....{
......// Check if player is nearby
......if (Vector3.Distance(transform.position,
......player.transform.position) <= 6)
......{
........// Move toward player
........agent.SetDestination(player.transform.position);
........// Pass the movement velocity to animator
........animator.SetFloat("runningSpeed",
........agent.velocity.magnitude);
......}
....}
..}

public void GetDamage (float damage)
..{
....healthPoint -= damage;
....if (healthPoint <= 0)
....{
......Die ();
....}
..}

void Die ()
..{
....Destroy (gameObject);
..}
}

Before the monsters are able to chase the player, you need to open up the Navigation panel by going to Window | Navigation and click on the Bake button on top and then click again on the Bake button in the lower-right corner. After several seconds, you will see blue polygons being generated all over the level. These blue polygons are what we call navigation meshes and are used by the Nav Mesh Agent to calculate path finding.

These are the options for navigation mesh baking:

  • Agent Radius: This option defines how close the bake agent can get to a wall or a ledge.
  • Agent Height: This option determines the height that can be reached by the bake agent.
  • Max Slope: This option defines how steep the ramps are that the bake agent walks up.
  • Step Height: This option determines how high the obstructions are that the bake agent can step on.
  • Drop Height: This parameter controls the highest distance for the bake agent to link two off-link meshes for dropping.
  • Jump Distance: This option determines the further distance for the bake agent to link two off-link meshes for jumping.
  • Manual Voxel Size: This option enables you to change the voxel size manually, which sets the accuracy of the baking process.
  • Voxel Size: The default setting resulting in 3 voxels per agent radius, which means the whole agent width is 6 voxel. Changing this value will affect both the accuracy as well as the baking speed.
  • Min Region Area: Using this option, regions that have a surface area smaller than the specified value will be removed.
  • Height Mesh: By enabling this option, you can get a more accurate placement of your character on the navmesh surface. However, this will take up more memory and processing at runtime, and it will also take a little longer to bake the mesh.

Once you have generated the navigation meshes, try duplicating the monster prefabs across the level and have fun getting chased by them!

Summary

In this article, you have learned how to create basic AI that can chase you around in your game.

Resources for Article:


Further resources on this subject:


You've been reading an excerpt of:

Building a Game with Unity and Blender

Explore Title