Home and Learn: Games Programming Course
In this lesson, you'll get a character patrolling through a set number of points. We'll use the same project as in the previous lessons, where we just had the one destination. There's not a great deal that's different. We only need to add the patrol points and attach a different C# script.
In the Hierarchy on the left, right-click and add an empty game object. Call it PATROLPOINTS. Now drag and drop your Cube onto your new empty game object. Rename the cube to PatrolPoint_1:
Move PatrolPoint_1 to the bottom of the stairs:
With PatrolPoint_1 selected, press CTRL + D to duplicate PatrolPoint_1. (Or right-click PatrolPoint_1 and select Duplicate from the menu that appears.)
Rename PatrolPoint_1 to PatrolPoint_2. Move PatrolPoint_2 to the top of the stairs.
Create two more Patrol Points the same way. Rename them to PatrolPoint_3 and PatrolPoint_4. Move PatrolPoint_3 to just through the arch, and move PatrolPoint_4 to the top of the slope:
Now to add the script.
Our script will take an array of game objects and then loop through them.
With your Capsule selected, click the Add Component button in the Inspector. Create a new C# script. Name it PatrolPoints:
Make sure to deselect the Move To Destination script by unchecking the box indicated in the image above. Now double click on your new script to open it up in the editor.
When your editor opens, select all the code in the editor and delete it. Now replace it with the following (you can copy and paste):
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(NavMeshAgent))]
public class NavDest : MonoBehaviour
{
NavMeshAgent patrol_agent;
public Transform[] patrol_points = new Transform[4];
private int patrol_points_index = 0;
void Start()
{
patrol_agent = GetComponent<NavMeshAgent>();
}
void Update()
{
float distance = Vector3.Distance(patrol_agent.transform.position, patrol_points[patrol_points_index].position);
if (distance < 0.5f)
{
patrol_points_index = patrol_points_index != patrol_points.Length - 1 ? patrol_points_index + 1: 0;
}
patrol_agent.destination = patrol_points[patrol_points_index].position;
}
}
We'll go through the code soon, but it's a modification of the code in the samples folder you imported at the start of these tutorials. You can find the Unity code here in your Projects area:
Assets/Samples/AI Navigation/1.1.5/Build And Connect NavMesh Surfaces/Scripts/NavigationLoop.cs
In the script editor, save the code you copied and pasted. Now go back
to Unity. With the Capsule still selected, take a look at the Inspector
on the right, and expand the patrol_points item. You will see that
there are four elements, labelled 0 to 3:
This is an array you need to fill. There are four elements because we set it up for 4 patrol points in the code:
public Transform[] patrol_points = new Transform[4];
If you want more patrol points (or fewer), just change the 4 in the script into however many number of patrol points you need.
But click the circle to the right of the first element to bring up the popup box:
Select PatrolPoint_1. Fill the rest of the array with the other patrol points:
Now try it out. You should notice a problem - the capsule character stops at the first patrol point!
The reason the capsule character stops at the first point is because
it's too big to get through the arch. The NavMeshAgent calculates the
next few destinations and figures it's going to be in trouble further
down the line. So it just stops. The solution is to make the capsule smaller.
With the capsule selected in the Hierarchy, change the X, Y, and Z values
for the Scale. Change them all to 0.4:
Run the game again and you should see the capsule moving to all patrol points:
Of course, you won't want those yellow squares showing up in your game.
To hide them, select all your patrol points in the Hierarchy on the left.
In the Inspector on the right, uncheck the Mesh Renderer item:
Play your game again to see how it looks.
One last thing you can do. It looks like the character is gliding up the steps. If you want a character to look as though it is walking up the steps, check the box Build Height Mesh on the NavMeshSurface:
Click the Bake button again and rerun your game to see what it looks like.
If you're interested, here is a review of the code.
Before the Class starts, we tell Unity that the NavMeshAgent is a required component. Inside the Class, we set up some variables:
NavMeshAgent patrol_agent;
public Transform[] patrol_points = new Transform[4];
private int patrol_points_index = 0;
The first one is a NavMeshAgent. We've called our NavMeshAgent variable patrol_agent.
Next, we set an array of Transforms:
public Transform[] patrol_points = new Transform[4];
It's public so that the array will show up in the Inspector. We want 4 elements in the array, one for each patrol point. Change the 4 here if you have more or fewer patrol points.
The final variable is called patrol_points_index. It's just a private integer that we set to a value of 0, the first element in our Transform array.
In the Start method, we need to get the NavMesgAgent component:
void Start()
patrol_agent = GetComponent<NavMeshAgent>();
}
This will get us a reference to the NavMesgAgent component attached to the Capsule.
The rest of the code goes in the Update method. First, we have this long line:
float distance = Vector3.Distance(patrol_agent.transform.position, patrol_points[patrol_points_index].position);
This sets up a float called distance. What we're doing here is getting the distance between the Capsule and the patrol points.
CAPSULE: patrol_agent.transform.position
PATROL_POINT: patrol_points[patrol_points_index].position
If the distance between the two is less than 0.5, we execute this line:
patrol_points_index = patrol_points_index != patrol_points.Length - 1 ? patrol_points_index + 1: 0;
This is really just another IF statement. It reads, "If the patrol_points_index DOES NOT EQUAL the length of the patrol_points array minus 1, then increment the patrol_points_index variable. Otherwise, if it is the last element in the array (minus 1), we reset the patrol_points_index to 0. It's a loop, really.
The final line is this:
patrol_agent.destination = patrol_points[patrol_points_index].position;
Here, we set the destination for the patrol agent (our capsule). We set it to the position of whatever patrol point is currently in the patrol_points array
And that's it - a relatively simple way to get a character to patrol using Unity's AI Navigation. In the next lesson, we'll add a few obstacles. The capsule character will then move around the obstacles. You'll also see a few more settings you can tweak.
In the next lesson below, you'll learn how to get an AI enemy to jump up onto things like platforms and chase the player.
<--Back to the Unity 3D Course Contents Page
Email us: enquiry at homeandlearn.co.uk