In this lecture, we will start looking at one of the most fundamental A.I. techniques used in navigation: Waypoints.
Waypoints are simply positions on a map that, when navigated in sequence, produce a path.
It's the same system used in a car G.P.S.
that gives you instructions on where to drive. Waypoints are an easy system to implement in an NPC as
it makes them look more intelligent than they
are
and by providing them with a safe set of locations on a map to move between, they can also avoid obstacles.
We've already created an NPC that can move and follow a goal location. Updating this to a waypoint
system is straightforward. To follow along,
download the project associated with this lecture and open the tank scene. In the scene, you'll find a little
purple tank
and it's this little purple tank that will be our NPC. To begin, we need to create some
waypoints
and I usually create my waypoints from spheres so that I can see where they are.
So over in the Hierarchy, right-click and go 3D Object > Sphere and that will create a sphere for you.
I'm also going to color it in red. There's a red material in this project file.
This is just so that we can see it
and you also want to take off the Sphere Collider as well because you don't want it to be a physics object.
All this is, is a marker for our tank to navigate around.
Later on, you may even turn off your mesh renderer when you don't want to see the waypoints, but when you're
editing them it's good if you know where they are 'exactly', rather than just a transform.
Right, so this is a waypoint
and in order to make it a waypoint, I've created a tag and you'll need to assign this tag to this sphere,
so just go over to the Inspector and look through the list and you'll find 'waypoint'.
If it's not there (or you're creating your own system) you'll need to add a tag and then come back and
reassign your waypoint tag to this sphere.
Take notice also how it's spelled
because we're going to search for it later.
So this is 'waypoint' all in lowercase.
So there's our first waypoint.
Now with that created, you can move it into place and then Ctrl-D and make multiple copies of it
and make a little circuit for the tank to move around.
It doesn't even need to be perfectly round.
Just go with something like that.
Next, we'll create a script that will follow the waypoints.
So go to Project > Create > C# Script...let's call this WaypointFollow
and open it up and we'll add in the following code.
The code includes a lot of the stuff that we've done before and that we did with our zombie example of
moving her around and following and slerping.
So you'll see those same dynamics in a moment when we get down there.
First of all, though, you need an array of game objects to hold all of those waypoints and we're going
to populate that automatically.
Next, an 'int' which is the current waypoint.
So it's the index into this waypoint array for the sphere we're currently heading towards.
After that, you've got the usual suspects that we've had before with speed, accuracy and rotational
speed.
Now in the Start function, we're setting the waypoint array to equal all of the game objects that
have the tag 'waypoint'.
So this is automatically filling up this waypoint array for you.
If you wanted to specify the waypoints yourself, you could manually drop them into this waypoint
array through the Inspector and then you could put them in the order that you want them in.
But for now, we're just doing this automatically because it's just way quicker. In the LateUpdate is
where all of the work is going to happen and you can see it's quite short really.
First of all, we're going to check if we have any waypoints. If we don't, then we're just going
to return because there's no point moving anywhere.
Then we have our lookAtGoal being constructed again.
Again, this is a 2D kind of LookAt, as far as it being at the same height as the tank
but in the x and z of the waypoint. If you wanted a 3D system of waypoints, where you've got
an airplane or you've got a bird or something that can move in three dimensions, then you would obviously
put the waypoints y-position in here, instead of the tanks
y-position.
We then calculate our direction as before
and then we perform the slerp, which will turn the tank towards the waypoint (or in that direction).
Right.
We then go ahead and test our magnitude for being 'less than' accuracy, to say whether we're close enough
to that particular waypoint.
If we are close enough to the particular waypoint, then we increase our waypoint that we're heading
to by 1.
So let's say we're heading to waypoint 0
and then we've reached it within our accuracy,
this will then go to waypoint 1 and that will cause us to start looking at waypoint 1 and moving
to waypoint 1.
All right.
Now if we've reached the end of that array, we've run out of waypoints. Then we just go back to the first
waypoint.
So this is going to cycle around for us. After all that happens, we're then going to perform our Translate.
Notice the Translate is not restricted in any way, it's just going to happen regardless of anything
except there being no waypoints at all. So we're turning, we're looking at the waypoint we
should be looking at and then we're pushing the tank forward because this whole update is about cycling
around the waypoints, so the tank will never stop at anything.
Save that, then go back to Unity and what you want to do is select your tank and drag-and-drop
WaypointFollow on to the tank.
Now in the Inspector, you'll see the waypoints here.
Now if you wanted to put your waypoints in, you could drag-and-drop them, as I said before, from the Hierarchy
on to that array and then put them in and change the order that you want
but we're doing this automatically, so there's no need to in this case.
So once you've done that, press Play and you'll find that the tank starts to follow your
waypoints around.
Ok, so it's off to this one...
and then it will turn and go to this one...
If this is a little bit slow for you,
we just go back into the waypoints and modify the speed.
Let's put this up to 3.
Now if you increase the speed, you also need to increase the rotational speed as well,
otherwise you'll find that you get a tank that does an
awful lot of swinging around in big arcs.
So let's see if this helps.
Not too bad.
You can see that it does take a quite a big arc to turn because that rotational speed's a bit slower
than the actual forward speed, but it still works.
It gets close enough to the points.
Now remember, if you get a tank that starts to go around a waypoint or starts to jitter on a waypoint,
it's because the accuracy is too low and you'll need to increase your accuracy.
Let's see if we can force the tank to do that.
Open up your script and the accuracy (which is currently 1), let's make it 0.5.
Save that and go let's go back and run this
and let's see, if the tank never reaches the waypoint, it will just start to circle the waypoint because
it's constantly changing its direction vector to point at the sphere, whilst it's being pushed forward
as well.
Now it just can't get close enough because of the speed and the rotation to make it within that
0.5 distance of that waypoint
and therefore it's just going to be stuck.
So it's the speed, the rotational speed and the accuracy that ALL have an effect on whether the tank will
reach that particular waypoint or not.
So always consider those and check out what's going on as far as the behavior is concerned.