‫Hello and welcome.
‫This lecture, we're going to be making our enemy more of a threat by implementing a shoot node in C++.
‫Let's dive in and see how to do it.
‫So one piece of functionality that's clearly missing from our behavior tree is the ability to shoot.
‫What I'd ideally want to do is move to the player's location and then shoot.
‫But we want to change a little bit first how we do the movement.
‫There's a couple of things I want to tweak, so if I select the move to Node, one thing I want to change
‫is the radius.
‫I don't want the enemy to be coming right up to me, so if I change the acceptable radius, then it's
‫going to stop moving five meters away from me.
‫So it's going to stop.
‫Give me a nice five metre distance.
‫He comes up to me, there you go.
‫And he stops and stares.
‫Now the other thing I want to do is down here in the blackboard section, you can see there is an observed
‫blackboard value.
‫If we don't have that checked, let's see what happens as I move.
‫He basically and this was slightly more obvious when we had a smaller acceptable radius.
‫So let's just stick that down there to five four now.
‫And if I hit play then you can see that as I move.
‫He goes to my last location and then he only then when he's reached that, does he come an update.
‫That's not what we want.
‫What we want is it to be constantly coming towards us.
‫And if you check the observe blackboard value, then essentially what it's saying is that every time
‫the player location changes, we're going to update where we are moving to.
‫So if I go ahead and hit play and move, you can see he's continuously following me and updating his
‫path.
‫That's exactly what we want.
‫So now we can change our accept radius to 500 and it becomes less obvious.
‫But it's still good that we have our observed blackboard value there.
‫And then the behavior that we want is that once he comes within radius of us like so he's going to stop
‫and shoot at us.
‫For that we need a new type of task.
‫So we're going to create a new C++ task here.
‫So we're going to go to add new, new C++ class.
‫Then we're going to go and show all classes and look for the beat task.
‫Now, which one do we want, the beat task node or the beat task blackboard base?
‫Well, we don't actually need to use a key because we're just going to try and shoot.
‫That's all we're going to do.
‫We're going to pull the trigger on our gun or the aiming is going to be done elsewhere in our behavior
‫tree.
‫So let's open up the task node, the base class here, and we're going to call this beat task.
‫Underscore.
‫Shoot.
‫Let's go ahead and create that class.
‫Then we end up with something just like this.
‫So we want to do the same set up.
‫So a little bit of a mini challenge for you to do the same sort of set up as we've got for our blackboard,
‫clear blackboard value.
‫We want to have a name, we want to have an execute task.
‫Now suppose video and have a go at that.
‫Okay, welcome back.
‫So that was a mini task.
‫I'm just going to copy over the signatures from a clear blackboard value over to shoot, including the
‫public and protected sections.
‫I'm going to change the name of our constructor.
‫I'm going to go ahead and implement our constructor.
‫And what was it that we needed to do?
‫We needed to set node name equal to shoot.
‫That's what we're going to call it.
‫Then back to the header for the shoot task and we're going to try and implement the execute task now
‫and we just need to call up to super.
‫So I'm going to copy that from our clear blackboard value CP file and then we are ready to start implementing.
‫So the first thing we're going to need to do here, let's have a bit more space is we're going to need
‫to get hold of our pawn.
‫Why do we need to get hold of our pawn?
‫Well, let's have a look at the shooter character, which is a pawn.
‫Remember the shooter character?
‫Dot H has a shoot method.
‫That's what we want to be calling essentially the same as we as the player is doing.
‫He's holding down the trigger button and that's calling this shoot method.
‫We want the AI to be able to do the same.
‫When you have the shoot task, it's going to hold down the trigger button or repeatedly press that trigger
‫button so the execute task is going to be the right place to do this.
‫We're probably going to return what here, because remember, this action is just one shot.
‫It's not continuous shooting.
‫What are we going to do?
‫We're going to return the ET node result success if we or succeeded.
‫If we succeeded because we don't need to continuously cool tick.
‫We don't need this task to be running any longer than a single frame.
‫And the other thing we need to do is get hold, as I said, of that pawn class.
‫Well, what I'm going to do is I'm going to show you how you can get hold of the AI controller.
‫And from the AI controller, we know that we can call get pawn to get the pawn that was controlled.
‫And we know that we can cast that controlled pawn to our shooter character implementation.
‫So how do we get hold of the AI controller from this?
‫Well, we've got our behavior tree component, which we know is on an AI controller.
‫So maybe that has something that we can use if we go to the Yu behavior tree component and have a look
‫in here for any methods that might be helpful.
‫There's a lot in here, but if we look for controller, we aren't seeing anything but maybe somewhere
‫in one of its base classes because the parent class for the YU behavior tree component is the Yu brain
‫component.
‫We follow up to that one and look for controller in here.
‫You can see there is a property for it.
‫Is there a getter?
‫Yes, there is called get AI owner and that should return if we hover over it an AI controller pointer.
‫So you should be able to use that to get hold of the pawn, cast it to a shooter character and then
‫call the shoot method.
‫So that's going to be your challenge to call the shoot method, make it public, get the pawn, cast
‫the pawn, call, shoot and then test it out in your behavior tree.
‫Pause the video and have a go.
‫Okay.
‫Welcome back.
‫So, first of all, first step is we're going to need to make this shoot method public because it needs
‫to be called from outside of this class.
‫So I'll put it just undertake damage.
‫We'll have shoot, give a little bit of space to it, a little breathing room.
‫I like white space helps me see.
‫Help me think.
‫Then we're going to go to the BT task shoot.
‫We're going to first of all check that our controller is not null.
‫Otherwise we can't use the arrow operator on it.
‫Just general, good practice to do these null checks.
‫So if this AI owner is not equal, sorry is equal to null pointer, we're going to want to return early
‫with a failure.
‫So this task will fail if we don't have an AI controller.
‫That's pretty straightforward.
‫So I'm going to do a return ET node result colon.
‫Colon failed like so.
‫And then we are going to do the owner component, get AI owner, we're going to get -- on it.
‫In fact, we might need to include a header file here.
‫So let's do a hash include and it's going to be game framework and the controller.
‫And in fact I think, yeah, any controller should do, but I think we need the AI controller because
‫that's the type of the pointer that we're going back and then we're going to do an arrow and we're going
‫to do a get pawn here complaining about something in my head of file.
‫Maybe I haven't got something right.
‫So forward slash I looks like I got it wrong.
‫It's not actually in game framework.
‫You just have a controller to include that.
‫Teach me for being so blasé about that.
‫So there we go.
‫We can now get the pawn from the.
‫And as I said, we also need to do a cast.
‫So we're going to do a cast to what type we're going to need to cast to the A of the shooter character.
‫So that is in its full form a shooter character, a shooter character.
‫And we're going to need to check the result of this as well.
‫But we need to include our shooter character.
‫So hash include at the top the shooter character.
‫Todd H.
‫Like so and we're going to store that in a pointer type shooter character.
‫Star is going to be our character.
‫That's what we'll call it.
‫We'll store it there.
‫And basically we need to make sure that neither the get -- returned because get -- might return
‫null if the eye is not currently controlling a pawn.
‫Or this cast might return null if the type is not an issue to character if his controlling a different
‫type of --.
‫Fortunately, these two go down quite well together, so if you try and cast a null pointer, the result
‫is just a null pointer, which is why we can do this.
‫These checks all in one line.
‫Then we can do an if character.
‫Equals null pointer.
‫Then we want to fail again.
‫So return.
‫ET node result.
‫Colon.
‫Colon failed like so.
‫And finally, after all of those checks and we know that we've got ourselves a shooter character, we
‫should be able to call shoot so character arrow and shoot like so so that will finally get us able to
‫shoot.
‫Let's go over to our behavior tree.
‫And in here we're going to want to pull down to place a new node and look for the new shoot task that
‫we've got in here.
‫And I'm not sure whether I compiled, so I'm just going to make sure that everything compiles again.
‫And once that's done, we can go over and hit play and see if this guy comes up and shoots.
‫Yes, he does.
‫Unfortunately, he's shooting repeatedly and shooting himself in the foot.
‫So something is not quite writing right there.
‫So there's two things going wrong.
‫For a start, he managed to kill himself with two shots, and it also seems like he is shooting every
‫single frame, which would make sense because we're getting to see the player, we move to them and
‫then shoot is the last action we've got here, which we're going to execute repeatedly.
‫So what we want to do is actually turn this into a sequence.
‫So I'm going to drag off a node here called make a sequence node.
‫And what we're going to do is we're going to shoot, then wait, then shoot, then wait and repeat that
‫indefinitely.
‫So shoot first, wait a little bit.
‫So maybe we wait, I don't know, for 1/2 between shots and then we're going to want to repeat this,
‫which we can do with a decorator.
‫So if I right click add decorator and look for the loop decorator, then you can see how many times
‫you want it to loop.
‫It says three times.
‫We don't want it three times.
‫We want it basically to infinitely loop until we need to move or we need lost sight of the player and
‫we need to go and investigate.
‫So we're going to go ahead and hit play and see if that works.
‫Comes up to me.
‫Shoots, shoots, shoots.
‫But he's not actually hitting me.
‫You can see that his shots are actually landing on himself.
‫And we're going to deal with that bug in an upcoming lecture.
‫See you there.