In the previous lecture we set up the basics of our behaviour tree and printed out the actual nodes
and the structure that they come in.
Now the nodes on the very bottom are the leaf nodes.
They're the ones that are going to do the work and cause our agent, which is our robber in this case,
to actually move around the map, which is simulating him actually doing something.
So the first set of behaviours we've got is going to Diamond and then going back to the van.
Okay.
So first things first, our little agent down here, our robber, if you click on him in the hierarchy
and have a look over in the inspector, you'll see that he already has a nav mesh agent on there.
So we need to get hold of that nav mesh agent inside of the script.
We also need to know in that script the location of the diamond, which is over in this part of the
gallery and also the van which is over here.
And those two objects are in the hierarchy, of course.
So we've got them as well, and we can pass them through to the script for the robber.
So let's just go into there and up the top here.
We're going to pass those in.
So we want a public game object and that will be our diamond.
And then we want a public game object.
Van.
Now we also want to create our nav mesh agent here.
So up the top let's go using unity engine dot I.
And then down here we can actually create our agent.
So it's a nav mesh agent agent.
And to get hold of that just down in the start, we will go agent equals this dot get component nav
mesh agent.
Okay, so now we can actually direct him to go to the diamond.
So if we put down in the start here, for example, agent set destination and pass through the diamond
transformed position, he will then move there regardless of what the tree is doing.
This is just testing our agent set up with our nav mesh.
So just save that and we'll go into unity.
Select the rubber.
Now you're going to find Diamond and Van exposed in that script.
And so you can grab hold of the diamond, which is actually attached to this object called plinth.
And we will drag and drop that into diamond.
And the van itself is up here, getaway van and drag and drop that there.
Okay.
Now when we press play, that agent set destination is going to make him move along our nav mesh.
He's going to go through the nearest gap which is currently that door because it's actually only just
an empty object without any particular collider or anything.
And he goes over to the diamond.
Okay, so we know that the nav mesh part is now working.
We need to hook that all up with an actual action.
So an action has a process associated with it.
Let's go back into our code for the node and remind ourselves what's going on.
We've set up this status so that every node is going to return success if it's finished and it was successful
running if it's still running and failure if it's finished running and it's actually failed.
So there are three things now, where do these actually get returned from?
Well, they get returned from the process that happens within each node and depending on the type of
node will depend on the type of process.
So let's go down into here and I'm going to add in a new public virtual status process and this process
here, which is basically just the node level, because we're going to override all of these, we will
return status dot success as a default for that particular node.
Okay.
So just save that.
Now we're going to go into our behavior tree and give it a process.
So in the behavior tree, we're going to come in here and just above all this printing tree stuff,
we will put in a public override status process like that.
Now, we're not returning what the base does in this case.
What we're going to actually return in this tree is whatever the child returns, because remember that
your behavior tree has to run, its children doesn't run itself.
So every node, if it's got children, it runs the children.
And then based on what the children respond with, it then becomes that status.
So in here I'm going to run return children current child dot.
Process.
Then whatever it returns, that will be the status returned by the behavior tree.
And this actually makes the behavior tree then run the child objects process.
Now, in this case, our child objects, if we go back into our robber, are go to diamond and go to
Van.
Now, currently, if they run, they're just basic nodes, so they're going to return.
Success, which is pretty much useless to us at this point, means they're not actually doing anything.
So we need to create another class for leaves or a leaf.
So let's go back into unity.
We will right click down in our behavior tree, create a new script, let's call it Leaf.
Then we'll open that up in the editor.
Now Leaf is going to inherit from Node.
It's not going to have a start in an update so we can get rid of that.
Now, the leaf itself, this is going to be a little bit trickier because the leaves have to actually
run a particular process, which means there's going to be some method assigned to the leaf.
We don't know what that method is.
It could be anything.
So in this case, it's going to be for a start running that set agents destination.
That's what we want it to do because we're using a native mesh.
But if you're using some other kind of AI in your system, you might want to run a finite state machine
or you might want to run a neural network or something.
But whatever those processes do, they must end up returning one of our node statuses.
So either success, failure or running.
Now what are we going to do with these leaf nodes is actually create a delegate so that we can pass
through methods, so we can code up methods somewhere else and then pass them through and say, This
is what we want our leaf to run.
Okay?
Now the way we do that is we create a public delegate and it's going to return a node status.
So let's just put status and these are going to be called a tick.
So a tick is essentially one turnover for your behavior tree.
A tic is like a frame for the behavior tree, just like a frame happens when you run update in unity.
Okay.
So it's just sort of one, I guess, looping around that particular leaf or action in this case, then
we need a pointer to set up.
So public tic process method and that's the way we do it there.
Then we're going to override our process.
So public override status process again, we get rid of this base and instead what we're going to return
is the process method and the process method, it's going to return status.
So this is actually working out for us as long as we set up with this process method is here.
So up here I might just put if process method does not equal null, we can return that.
Otherwise we can return a status dot failure.
Oh, what is this Pennie doing.
Error checking.
Yes, I know.
It's very rare for me to do that, but I've done it for you there.
Okay.
And that will also remind you if you actually haven't set up a method for your leaf.
Okay, so we've done that.
How does the leaf know about the process method?
Well, we could go in the behavior a behavior and then actually assign it in there.
We could have like go to diamond dot process method equals this particular method or we could pass it
through by doing an override of our constructor.
So we want a public leaf which has pretty much nothing in it.
That's our empty one.
And then we want a public leaf and we're going to pass through a string for the name and then we want
to process method p m.
I like that.
And we're then going to sit named equal n and p m.
Process method to equal p m like that.
Now, this is not right.
That's got to be a tick like that.
So we're passing it through.
This is basically it's a pointer to our method that we're writing, passing it through, and then we're
setting it up to here.
So that then process method knows where it is down here and will actually run it for us and let's get
rid of that semicolon so it doesn't like it.
Okay, so we will now save this.
Let's go back into our robber and implement it.
So these diamonds and van's now become leaf instead like that.
And they're now wanting to be constructed from leaf and leaf and they actually need to have some kind
of method pass through as well.
So we'll go ahead and just write something really quickly that will satisfy that.
So under here, we're going to create a public node status.
It's got to be in a same format that the tick is constructed in.
So go to diamond like that.
And when we go to the diamond, we actually want to basically be running this here.
So let's take that out of there and we'll put it in here.
Okay?
And then we have to return something.
So let's just go return.
And in this case, let's make it a success.
So we will return node dot status, dot success.
Now notice here that the returning of the success here really has nothing to do whether your agent actually
made it to the destination or not.
Because at this moment I'm not really concerned about that.
I just want something that you can see at running.
Okay.
Then up in your go to diamond leaf, we're going to pass through, go to diamond.
And now the van actually needs a method pass through it as well.
Okay, so now it's time for a challenge.
What I'd like you to do is to write a go to Van method and set it up here with your leaf and write it
similar to what we've got for go to Diamond.
Don't make it too complicated.
We will fix all this up a little bit later.
We just want something that's going to run.
So follow this format here.
Pause the video.
Now, when we come back, I will show you how to do that.
Okay.
How did you go?
Well, really, all you needed to do was grab this, copy it and put it down here.
Call it, go to van, then down.
And your set destination.
You just want to put van.
And then up here in your leaf, we will put go to van.
All right.
So before we can play, we actually have to kick the tree off with a process of it because it's not
actually running its process.
And if we go into our behavior tree code, you'll see that it is ready to run the first child here in
process.
But we're not calling it.
So back in our code we actually need to go tree dot process like that to kick the whole thing off.
Now having another look through our tree, here's our tree.
We then have a intermediate node which is just a generic node at the moment.
We will modify that to something else a little bit later, but we're just leaving it at Node four.
Now, if we go into Node and have a look at the nodes process, you can see that it's going to return
success, which is kind of useless for us because we want it to then go and run its children events.
So instead I'm just going to replace this in here with the same code that I've got in the behavior tree,
which is going to be children current child dot.
Process.
Now, this is still not perfect, but it's enough to actually get part of our tree running.
So save that.
Save your rubber behavior, and then let's go and press play just so that you can see something working
at the end here.
Okay, great.
There we go.
So off he goes.
He's gone from the top level root of the tree to steel down to go to diamond.
Now, he's going to stop there.
He's not going to turn around and come back to the van, because if you have a look at the code, we're
only running the first child of any particular node.
The van is a second child of steel, so it's not actually running.
And the way that we currently have our nav mesh code set up to go to the destination isn't actually
correct either, but you at least have something that works that you can test.
Okay, so that is our action.
What are we going to do when we come back in the next lecture is actually fix up the nav mesh code and
put in some sort of proper code for go to Diamond and go to Van.