In this lecture, we're going to take a closer look at navmesh agents. To begin with, download the
NavMeshStationStarter project that comes with this lecture.
When you put it up, you'll find an extensive map inside there.
This is the map that came with the Angry Bots demo,
many versions of Unity ago.
I've stripped out most of the code and you'll find just the geometry in there. We'll just use this
as a 'play center' for our agents.
Now I'm going to zoom in on this bit here and
I've also moved my camera so that it's looking down on there when I press Play.
So go ahead and select this area here.
I've also created 2 materials that you won't have in your stuff. I've created
a blue material and a red material. This is just so that we can color the agents as we create them
to be able to tell the difference between them.
Next we'll set up the navmesh, so make sure you've got your navigation window somewhere in your project. To get that, it's
'Window > Navigation'. The next step is to select the geometry in your map that you want to become
part of the navmesh.
So go around and find the individual pieces of this model (so the individual polygons) and shift-select
them until you have most of the area where you want the agents to be able to move.
So we want to be able to go down the corridor, so make sure that you add that in and maybe these platforms.
If you want them to be able to jump up on things later on, you can add those.
If you don't select them all in one go, then you can come back and get them later.
Each of the meshes that you have selected needs to be set up to be a Static Navigation.
So select the Inspector, still with everything selected in the scene
and we want to go up to Static and drop that down and make sure that you've got Navigation
Static clicked,
just so the navmesh can pick it up. Once you've set those
(let me just set it again
because I might have turned it off) go back into the Navigation tab
and under Bake, click on [Bake]. Now the bits that are part of the navmesh are going to turn blue. At this
point,
if you've missed anything (so say you want this bit over here to be included) you can come back
and select it by itself and go to the Inspector and again, 'Static > Navigation Static', come back
to the navigation and under Bake, press [Bake] and that will add it.
So you can go through and do one bit at a time and keep adding it.
Now if you see something like I've got going on down here, where it's not blue and it's not blue there
either,
it's just an overlapped rendering problem.
So try not to worry about that too much.
The issue will be if your agents do not walk over that area, then it hasn't been picked up
for the navmesh and just come back, select it again and just make sure that you've got it set to
Navigation Static and then 'do a bake'.
Now it's time to add in an agent.
So let's just zoom out a little bit from here.
I'm going to go into the Hierarchy and we'll add in a new '3D Object > Capsule' and this capsule
is going to be our A.I. character and let's make that red so we can see
it, just drag that over there.
Now we're going to need to send this character some commands and we'll do that by tagging it, so that
we can find it. In the Inspector,
you want to create a new tag called 'ai' (which I've already created) so create that and then set your capsule
to be that. At that point, you can then change the name of this. Let's call it a 'RedAgent'.
We'll make it into a prefab a little bit later and then you can make multiple copies of them.
The important thing at this stage is that it's tagged as 'ai'.
I will now create a script called AIControl, so down in the project, create a C# script, call it AIControl
and you want to attach that to the RedAgent.
Now open it up and inside we want to grab hold of the navmesh agent that is attached to our character.
First, we add the library to access that, so 'Using UnityEngine.AI;' then we make a variable
to store the link to the agent in. So 'public NavMeshAgent agent;' and then in the start we set it up
to be the component that's on it.
So 'this.GetComponent' with NavMeshAgent, like that.
Now I want to program the agent so that it moves to a quick location on the screen and I could do it
down inside of the Update for this particular agent,
but if I'm going to have multiple copies of this agent around the place, I don't want them all running
their own Update with 'if' statements checking for mouse clicks and that type of thing.
So rather than do that, I will create an Agent Manager.
Let's go ahead and just remove this Update because I don't want an empty Update processing nothing because
it will cause significant lag if you do have a lot of agents trying to run an empty Update
and therefore we only need 1 update that will send the message through to all of the agents.
So I'm just going to save that, go back over here into the editor and in the Hierarchy, we'll right-click,
Create Empty and give it the name of AgentManager
and then what I'll also do is create a script called AgentManager. That script gets attached to our
AgentManager game object (funnily enough) and then inside of the script, we're going to add this.
So this script has an array of agents at the top which gets populated when we start playing.
So 'agents' will be filled up with all of the game objects in the scene that have the tag 'ai'. That's why
'ai' is so important that you've tagged your agents with it then the clicking on the environment to
get the agent to move there is going to happen in the Update.
So no matter how many agents you've got tagged as 'ai' in your scene, this message will be sent to them.
So if a mouse button is clicked (in this case, the left mouse button) then we'll
create a RaycastHit
We'll use a physics raycast from the mouse input position via a ScreenPointToRay so it shoots
a straight line out from the position of the mouse on the screen into the scene and finds out where it
hits, within a distance of 100.
If you find you're not hitting anything and you're clicking all over the place, increase
this number here, so that you're producing a longer ray. Then inside of the 'if' statement, we've got a foreach
and that's just going to loop around all of the agents in the array
and for each one of them, it'll grab hold of their AIControl script and get their agent that we just set
up for them.
Like in the last lecture, we used the SetDestination and that will pass through the position of where
the mouse click was. So it's a Vector3 value that's going to go in here, to the navmesh agent
and because the navmesh agent's already set up to move around automatically,
it will start moving towards that hit point.
So let's save that
and back in the editor, let's grab hold of our RedAgent which has the script on it, but it doesn't yet
have a navmesh agent, so just [Add Component] > Nav Mesh Agent.
Don't need to do anything else with that, we'll just leave the default values there.
Right, so press Play and we will be able to click somewhere on the area that we defined for our navmesh
and you'll see that the agent will now move.
Now if you wanted to move a little bit faster, we can select the agent and come down into the Inspector
and have a look for the Speed.
So it's currently set to 3.5 as default.
We can set that to 10, if you want it to go quite fast and press Play.
Actually, having said that, I don't think 10 is as fast as you might think. I can also click on here
because that's my navmesh and the only way to get into this area is if you go through this little tunnel.
Now you saw there that he got a bit stuck, or I should say overshot, where it was going to come down in
this path.
That's because of the speed and the acceleration and that type of thing as well as the braking.
Let me just stop this for a second.
What I want to show you is if you go to the Navigation window and select your agent and then press Play
you'll be able to see the navmesh and how it works.
When you click on the surface, you'll see the path that gets calculated. So let's say you want to
go over here.
You can see all the polygons that are chosen as part of the path. The agent itself also ends
up with some vectors sticking out of it, showing you the direction that it's traveling in and how it's
turning, where it's going to be facing towards
and those sorts of things as well. Where the agent can move throughout the navmesh is all dependent
on the 'Baked Agent Size'. Over in the Navigation window, under Bake, there is a Baked Agent Size
that you would have seen before and changing the values on this determines how the navmesh size is generated.
So for example, the Agent Radius, if we were to increase that to say that our agent is quite wide
and then rebake, what you're going to do is find any narrow areas where it could get through before are
now gone.
So, for example, the agent can't get down this tunnel any more because it was really one of the narrowest
sections
and despite the fact that if you select this 'Agents' tab up here and have a look what's going on here,
you can modify the size of any particular type of agent which we'll look at later on,
it still has no effect whatsoever over this Baked Agent Size.
So it's the Baked Agent Size that determines how the navmesh gets generated on the surface of your environment,
NOT the size of the individual agents that you might create. You could have Humanoid, Zombie,
Fish, whatever you want, you can have all different types of A.I. but they will not affect the baking of
the navmesh,
this will in here.
So if we bring this back down to 59 and rebake it, we'll get our little path underneath this tunnel again.
Even if I had a different agent in here and he was absolutely enormous and he was bigger than
0.59 in radius, he would still be able to follow the path and he would work his way through the
geometry, so probably not something you want and you CAN control that but not right here.
The other thing you can set is the slope that the agent can walk down.
So if I just move this over and have a look down here, in this lounge area there's a slope from this platform down
into there and we can change this over in the Bake area. The 'Max Slope' that that agent's able to navigate
is currently set to 45.
If we said that this agent just can't use slopes whatsoever and set it to 0 and then rebake it,
you'll see that there now is no path that the agent can take to get there.
Now in taking this out, you might have also disturbed the path from where the agent currently is elsewhere
and let's have a look over here. You can see that the path over this section here is now gone as well.
Now even if I press Play at this point, I can click legitimately in these areas but the agent can't get there.
So if I click out here, he can move to there
but if I try and get him to come in to here,
it's going to follow the path as far as it can until it gets stuck.
Now you can see in this case what's happened, it's over
here now, is because it tried to calculate the shortest path to get to here and because it couldn't go
this way, it went all the way around the back and then it got as close as it possibly could to there
but couldn't reach it.
So if we click over here, the agent can come over here
but, of course, it can't get through there because there's no path
and if we click down this area here, again there's just no way to get there
so it won't, even though it does try. Underneath, where you set the Maximum Slope, you can also set the
Step Height
and this is really great if you've got environment with lots of steps and you want your agents to get up
on top of things. In this environment,
there's not really any steps, but let me have a look around.
There's a container here.
Now this container, you can navigate on top of it
if you're already on top of it. There's no path to get up on top of this container.
If I select this container (and I'm just going to move it over to there, where we can see it clearly, let's get that box out
of the road) and then if we bake right now you'll see that it gets the top on it, but we still can't get
up there. It's too high.
So I'm going to move it down into the ground a bit,
so maybe about...there and press [Bake]. Now when we press Play, we'll see if we can get up on top of it.
So we'll go over there and the agent goes near it, but it can't get up on top of it. So it's close, but not quite.
Let's just make that step a bit higher.
You can't make a step higher than your agents.
So Unity will stop you if you try and do it.
Ok,
now what you can see is that it has drawn up the side of the box here, which clearly shows us that the path
for that step exists.
So now when I press Play and I click on the box, he's going to pop up on top.
So there it is there and then he will also be able to get off again as well.
So it's like the jumping height, as well as for going up stairs. Just to finish up with
this lecture,
what I'm going to do is go back to the Bake and we will increase our slope again so that we can get
inside of that area and bake that. Ok, it brings this path back here
and then with Agent itself (our RedAgent) we can just Ctrl-D and make a whole bunch of copies of it.
Now they're going to be all exactly the same.
They're all going to have the same tag of 'ai' which means the AgentManager will pick them up and send through any
click messages to them, which will set their destination. Now before they even move,
their physics will not make them collide with each other and they won't use their own avoidance system to
avoid each other either because we haven't triggered that to happen.
But as soon as I click in here they will all pop apart and now you can see them all seemingly working
together to get the same location.
But all they're doing is just trying to get to where you've clicked whilst avoiding each other.
So you can have as many of these little red guys as you like
and the AgentManager will automatically pick them up for you.
All right, so that is the basics of creating a single agent and some of the nuances of the map and setting
up the navigatable areas on there. In the next lecture, we'll look at adding a different agent type so
that we have 2
and restricting where they can go.