﻿1
00:00:04,290 --> 00:00:05,340
‫Hello and welcome.

2
00:00:05,340 --> 00:00:11,610
‫This lecture, we're going to be making our enemy more of a threat by implementing a shoot node in C++.

3
00:00:11,610 --> 00:00:13,800
‫Let's dive in and see how to do it.

4
00:00:14,580 --> 00:00:19,980
‫So one piece of functionality that's clearly missing from our behavior tree is the ability to shoot.

5
00:00:19,980 --> 00:00:24,930
‫What I'd ideally want to do is move to the player's location and then shoot.

6
00:00:24,930 --> 00:00:28,560
‫But we want to change a little bit first how we do the movement.

7
00:00:28,560 --> 00:00:33,150
‫There's a couple of things I want to tweak, so if I select the move to Node, one thing I want to change

8
00:00:33,150 --> 00:00:34,290
‫is the radius.

9
00:00:34,290 --> 00:00:39,990
‫I don't want the enemy to be coming right up to me, so if I change the acceptable radius, then it's

10
00:00:39,990 --> 00:00:42,930
‫going to stop moving five meters away from me.

11
00:00:42,930 --> 00:00:43,740
‫So it's going to stop.

12
00:00:43,740 --> 00:00:45,690
‫Give me a nice five metre distance.

13
00:00:45,690 --> 00:00:46,650
‫He comes up to me, there you go.

14
00:00:46,650 --> 00:00:48,180
‫And he stops and stares.

15
00:00:48,180 --> 00:00:53,670
‫Now the other thing I want to do is down here in the blackboard section, you can see there is an observed

16
00:00:53,670 --> 00:00:54,780
‫blackboard value.

17
00:00:54,780 --> 00:00:58,470
‫If we don't have that checked, let's see what happens as I move.

18
00:00:58,500 --> 00:01:03,660
‫He basically and this was slightly more obvious when we had a smaller acceptable radius.

19
00:01:03,660 --> 00:01:06,780
‫So let's just stick that down there to five four now.

20
00:01:06,990 --> 00:01:09,840
‫And if I hit play then you can see that as I move.

21
00:01:09,840 --> 00:01:14,940
‫He goes to my last location and then he only then when he's reached that, does he come an update.

22
00:01:14,940 --> 00:01:16,320
‫That's not what we want.

23
00:01:16,320 --> 00:01:19,530
‫What we want is it to be constantly coming towards us.

24
00:01:19,530 --> 00:01:25,320
‫And if you check the observe blackboard value, then essentially what it's saying is that every time

25
00:01:25,320 --> 00:01:30,180
‫the player location changes, we're going to update where we are moving to.

26
00:01:30,180 --> 00:01:36,930
‫So if I go ahead and hit play and move, you can see he's continuously following me and updating his

27
00:01:36,930 --> 00:01:37,770
‫path.

28
00:01:37,770 --> 00:01:39,180
‫That's exactly what we want.

29
00:01:39,180 --> 00:01:43,830
‫So now we can change our accept radius to 500 and it becomes less obvious.

30
00:01:43,830 --> 00:01:47,250
‫But it's still good that we have our observed blackboard value there.

31
00:01:47,250 --> 00:01:53,220
‫And then the behavior that we want is that once he comes within radius of us like so he's going to stop

32
00:01:53,220 --> 00:01:54,330
‫and shoot at us.

33
00:01:54,330 --> 00:01:56,730
‫For that we need a new type of task.

34
00:01:56,730 --> 00:01:58,950
‫So we're going to create a new C++ task here.

35
00:01:58,950 --> 00:02:02,100
‫So we're going to go to add new, new C++ class.

36
00:02:02,100 --> 00:02:06,990
‫Then we're going to go and show all classes and look for the beat task.

37
00:02:07,020 --> 00:02:12,030
‫Now, which one do we want, the beat task node or the beat task blackboard base?

38
00:02:12,030 --> 00:02:16,500
‫Well, we don't actually need to use a key because we're just going to try and shoot.

39
00:02:16,500 --> 00:02:17,520
‫That's all we're going to do.

40
00:02:17,520 --> 00:02:23,040
‫We're going to pull the trigger on our gun or the aiming is going to be done elsewhere in our behavior

41
00:02:23,040 --> 00:02:23,520
‫tree.

42
00:02:23,610 --> 00:02:31,650
‫So let's open up the task node, the base class here, and we're going to call this beat task.

43
00:02:32,420 --> 00:02:33,320
‫Underscore.

44
00:02:33,350 --> 00:02:34,190
‫Shoot.

45
00:02:34,760 --> 00:02:36,700
‫Let's go ahead and create that class.

46
00:02:36,710 --> 00:02:39,470
‫Then we end up with something just like this.

47
00:02:39,470 --> 00:02:41,960
‫So we want to do the same set up.

48
00:02:41,960 --> 00:02:47,690
‫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,

49
00:02:47,690 --> 00:02:48,920
‫clear blackboard value.

50
00:02:48,920 --> 00:02:52,220
‫We want to have a name, we want to have an execute task.

51
00:02:52,220 --> 00:02:54,020
‫Now suppose video and have a go at that.

52
00:02:54,050 --> 00:02:54,920
‫Okay, welcome back.

53
00:02:54,920 --> 00:02:56,480
‫So that was a mini task.

54
00:02:56,480 --> 00:03:02,330
‫I'm just going to copy over the signatures from a clear blackboard value over to shoot, including the

55
00:03:02,330 --> 00:03:04,610
‫public and protected sections.

56
00:03:04,610 --> 00:03:07,640
‫I'm going to change the name of our constructor.

57
00:03:07,640 --> 00:03:10,130
‫I'm going to go ahead and implement our constructor.

58
00:03:10,130 --> 00:03:12,050
‫And what was it that we needed to do?

59
00:03:12,080 --> 00:03:16,490
‫We needed to set node name equal to shoot.

60
00:03:16,490 --> 00:03:17,690
‫That's what we're going to call it.

61
00:03:17,690 --> 00:03:23,420
‫Then back to the header for the shoot task and we're going to try and implement the execute task now

62
00:03:23,420 --> 00:03:25,820
‫and we just need to call up to super.

63
00:03:25,820 --> 00:03:32,600
‫So I'm going to copy that from our clear blackboard value CP file and then we are ready to start implementing.

64
00:03:32,600 --> 00:03:37,220
‫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

65
00:03:37,220 --> 00:03:39,860
‫to get hold of our pawn.

66
00:03:39,860 --> 00:03:41,540
‫Why do we need to get hold of our pawn?

67
00:03:41,540 --> 00:03:45,020
‫Well, let's have a look at the shooter character, which is a pawn.

68
00:03:45,020 --> 00:03:46,580
‫Remember the shooter character?

69
00:03:46,580 --> 00:03:48,890
‫Dot H has a shoot method.

70
00:03:48,890 --> 00:03:54,770
‫That's what we want to be calling essentially the same as we as the player is doing.

71
00:03:54,770 --> 00:03:58,460
‫He's holding down the trigger button and that's calling this shoot method.

72
00:03:58,460 --> 00:04:01,100
‫We want the AI to be able to do the same.

73
00:04:01,100 --> 00:04:06,830
‫When you have the shoot task, it's going to hold down the trigger button or repeatedly press that trigger

74
00:04:06,830 --> 00:04:10,070
‫button so the execute task is going to be the right place to do this.

75
00:04:10,100 --> 00:04:15,260
‫We're probably going to return what here, because remember, this action is just one shot.

76
00:04:15,260 --> 00:04:16,760
‫It's not continuous shooting.

77
00:04:16,760 --> 00:04:17,570
‫What are we going to do?

78
00:04:17,600 --> 00:04:22,430
‫We're going to return the ET node result success if we or succeeded.

79
00:04:22,430 --> 00:04:28,430
‫If we succeeded because we don't need to continuously cool tick.

80
00:04:28,430 --> 00:04:32,630
‫We don't need this task to be running any longer than a single frame.

81
00:04:32,630 --> 00:04:36,950
‫And the other thing we need to do is get hold, as I said, of that pawn class.

82
00:04:36,950 --> 00:04:41,330
‫Well, what I'm going to do is I'm going to show you how you can get hold of the AI controller.

83
00:04:41,330 --> 00:04:47,540
‫And from the AI controller, we know that we can call get pawn to get the pawn that was controlled.

84
00:04:47,540 --> 00:04:53,570
‫And we know that we can cast that controlled pawn to our shooter character implementation.

85
00:04:53,570 --> 00:04:58,850
‫So how do we get hold of the AI controller from this?

86
00:04:58,850 --> 00:05:03,560
‫Well, we've got our behavior tree component, which we know is on an AI controller.

87
00:05:03,560 --> 00:05:09,440
‫So maybe that has something that we can use if we go to the Yu behavior tree component and have a look

88
00:05:09,440 --> 00:05:12,350
‫in here for any methods that might be helpful.

89
00:05:12,350 --> 00:05:18,140
‫There's a lot in here, but if we look for controller, we aren't seeing anything but maybe somewhere

90
00:05:18,140 --> 00:05:23,750
‫in one of its base classes because the parent class for the YU behavior tree component is the Yu brain

91
00:05:23,750 --> 00:05:24,560
‫component.

92
00:05:24,560 --> 00:05:27,350
‫We follow up to that one and look for controller in here.

93
00:05:27,350 --> 00:05:29,420
‫You can see there is a property for it.

94
00:05:29,450 --> 00:05:31,100
‫Is there a getter?

95
00:05:31,100 --> 00:05:38,840
‫Yes, there is called get AI owner and that should return if we hover over it an AI controller pointer.

96
00:05:38,840 --> 00:05:44,450
‫So you should be able to use that to get hold of the pawn, cast it to a shooter character and then

97
00:05:44,450 --> 00:05:46,370
‫call the shoot method.

98
00:05:46,370 --> 00:05:51,740
‫So that's going to be your challenge to call the shoot method, make it public, get the pawn, cast

99
00:05:51,740 --> 00:05:56,480
‫the pawn, call, shoot and then test it out in your behavior tree.

100
00:05:56,480 --> 00:05:57,890
‫Pause the video and have a go.

101
00:05:57,980 --> 00:05:58,280
‫Okay.

102
00:05:58,280 --> 00:05:58,880
‫Welcome back.

103
00:05:58,880 --> 00:06:04,580
‫So, first of all, first step is we're going to need to make this shoot method public because it needs

104
00:06:04,580 --> 00:06:07,280
‫to be called from outside of this class.

105
00:06:07,280 --> 00:06:09,200
‫So I'll put it just undertake damage.

106
00:06:09,200 --> 00:06:12,200
‫We'll have shoot, give a little bit of space to it, a little breathing room.

107
00:06:12,200 --> 00:06:13,670
‫I like white space helps me see.

108
00:06:13,700 --> 00:06:14,540
‫Help me think.

109
00:06:14,540 --> 00:06:17,240
‫Then we're going to go to the BT task shoot.

110
00:06:17,240 --> 00:06:21,500
‫We're going to first of all check that our controller is not null.

111
00:06:21,500 --> 00:06:24,380
‫Otherwise we can't use the arrow operator on it.

112
00:06:24,380 --> 00:06:27,140
‫Just general, good practice to do these null checks.

113
00:06:27,140 --> 00:06:34,430
‫So if this AI owner is not equal, sorry is equal to null pointer, we're going to want to return early

114
00:06:34,430 --> 00:06:35,420
‫with a failure.

115
00:06:35,420 --> 00:06:38,570
‫So this task will fail if we don't have an AI controller.

116
00:06:38,570 --> 00:06:39,920
‫That's pretty straightforward.

117
00:06:39,920 --> 00:06:43,730
‫So I'm going to do a return ET node result colon.

118
00:06:43,730 --> 00:06:45,590
‫Colon failed like so.

119
00:06:45,590 --> 00:06:52,580
‫And then we are going to do the owner component, get AI owner, we're going to get -- on it.

120
00:06:52,580 --> 00:06:54,680
‫In fact, we might need to include a header file here.

121
00:06:54,680 --> 00:07:02,240
‫So let's do a hash include and it's going to be game framework and the controller.

122
00:07:02,240 --> 00:07:08,240
‫And in fact I think, yeah, any controller should do, but I think we need the AI controller because

123
00:07:08,240 --> 00:07:13,250
‫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

124
00:07:13,250 --> 00:07:16,850
‫to do a get pawn here complaining about something in my head of file.

125
00:07:16,850 --> 00:07:18,620
‫Maybe I haven't got something right.

126
00:07:18,620 --> 00:07:21,440
‫So forward slash I looks like I got it wrong.

127
00:07:21,440 --> 00:07:23,000
‫It's not actually in game framework.

128
00:07:23,000 --> 00:07:26,300
‫You just have a controller to include that.

129
00:07:26,300 --> 00:07:28,640
‫Teach me for being so blasé about that.

130
00:07:28,640 --> 00:07:29,180
‫So there we go.

131
00:07:29,180 --> 00:07:31,040
‫We can now get the pawn from the.

132
00:07:32,100 --> 00:07:34,890
‫And as I said, we also need to do a cast.

133
00:07:34,890 --> 00:07:41,610
‫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.

134
00:07:41,610 --> 00:07:45,780
‫So that is in its full form a shooter character, a shooter character.

135
00:07:45,780 --> 00:07:48,990
‫And we're going to need to check the result of this as well.

136
00:07:48,990 --> 00:07:51,360
‫But we need to include our shooter character.

137
00:07:51,360 --> 00:07:55,650
‫So hash include at the top the shooter character.

138
00:07:56,040 --> 00:07:57,000
‫Todd H.

139
00:07:57,570 --> 00:08:02,100
‫Like so and we're going to store that in a pointer type shooter character.

140
00:08:02,100 --> 00:08:04,440
‫Star is going to be our character.

141
00:08:04,650 --> 00:08:05,430
‫That's what we'll call it.

142
00:08:05,430 --> 00:08:06,510
‫We'll store it there.

143
00:08:06,870 --> 00:08:14,070
‫And basically we need to make sure that neither the get -- returned because get -- might return

144
00:08:14,070 --> 00:08:17,520
‫null if the eye is not currently controlling a pawn.

145
00:08:18,310 --> 00:08:24,850
‫Or this cast might return null if the type is not an issue to character if his controlling a different

146
00:08:24,850 --> 00:08:25,810
‫type of --.

147
00:08:25,840 --> 00:08:30,640
‫Fortunately, these two go down quite well together, so if you try and cast a null pointer, the result

148
00:08:30,640 --> 00:08:33,040
‫is just a null pointer, which is why we can do this.

149
00:08:33,130 --> 00:08:34,870
‫These checks all in one line.

150
00:08:35,380 --> 00:08:37,690
‫Then we can do an if character.

151
00:08:39,150 --> 00:08:41,250
‫Equals null pointer.

152
00:08:42,390 --> 00:08:44,670
‫Then we want to fail again.

153
00:08:44,670 --> 00:08:45,960
‫So return.

154
00:08:46,990 --> 00:08:49,090
‫ET node result.

155
00:08:49,480 --> 00:08:49,900
‫Colon.

156
00:08:49,900 --> 00:08:51,910
‫Colon failed like so.

157
00:08:51,910 --> 00:08:56,260
‫And finally, after all of those checks and we know that we've got ourselves a shooter character, we

158
00:08:56,260 --> 00:09:04,510
‫should be able to call shoot so character arrow and shoot like so so that will finally get us able to

159
00:09:04,510 --> 00:09:04,810
‫shoot.

160
00:09:04,810 --> 00:09:07,570
‫Let's go over to our behavior tree.

161
00:09:07,840 --> 00:09:15,070
‫And in here we're going to want to pull down to place a new node and look for the new shoot task that

162
00:09:15,070 --> 00:09:16,330
‫we've got in here.

163
00:09:16,330 --> 00:09:20,680
‫And I'm not sure whether I compiled, so I'm just going to make sure that everything compiles again.

164
00:09:20,680 --> 00:09:25,870
‫And once that's done, we can go over and hit play and see if this guy comes up and shoots.

165
00:09:26,560 --> 00:09:27,400
‫Yes, he does.

166
00:09:27,400 --> 00:09:32,860
‫Unfortunately, he's shooting repeatedly and shooting himself in the foot.

167
00:09:32,860 --> 00:09:35,950
‫So something is not quite writing right there.

168
00:09:35,950 --> 00:09:37,900
‫So there's two things going wrong.

169
00:09:37,900 --> 00:09:43,330
‫For a start, he managed to kill himself with two shots, and it also seems like he is shooting every

170
00:09:43,330 --> 00:09:48,160
‫single frame, which would make sense because we're getting to see the player, we move to them and

171
00:09:48,160 --> 00:09:52,210
‫then shoot is the last action we've got here, which we're going to execute repeatedly.

172
00:09:52,210 --> 00:09:56,350
‫So what we want to do is actually turn this into a sequence.

173
00:09:56,350 --> 00:10:00,280
‫So I'm going to drag off a node here called make a sequence node.

174
00:10:00,280 --> 00:10:04,120
‫And what we're going to do is we're going to shoot, then wait, then shoot, then wait and repeat that

175
00:10:04,120 --> 00:10:04,810
‫indefinitely.

176
00:10:04,810 --> 00:10:07,690
‫So shoot first, wait a little bit.

177
00:10:07,690 --> 00:10:13,510
‫So maybe we wait, I don't know, for 1/2 between shots and then we're going to want to repeat this,

178
00:10:13,510 --> 00:10:14,950
‫which we can do with a decorator.

179
00:10:14,950 --> 00:10:20,470
‫So if I right click add decorator and look for the loop decorator, then you can see how many times

180
00:10:20,470 --> 00:10:21,490
‫you want it to loop.

181
00:10:21,520 --> 00:10:22,540
‫It says three times.

182
00:10:22,540 --> 00:10:23,470
‫We don't want it three times.

183
00:10:23,470 --> 00:10:29,020
‫We want it basically to infinitely loop until we need to move or we need lost sight of the player and

184
00:10:29,020 --> 00:10:30,340
‫we need to go and investigate.

185
00:10:30,430 --> 00:10:32,970
‫So we're going to go ahead and hit play and see if that works.

186
00:10:32,990 --> 00:10:33,610
‫Comes up to me.

187
00:10:33,610 --> 00:10:35,890
‫Shoots, shoots, shoots.

188
00:10:35,890 --> 00:10:37,510
‫But he's not actually hitting me.

189
00:10:37,510 --> 00:10:41,860
‫You can see that his shots are actually landing on himself.

190
00:10:42,520 --> 00:10:46,660
‫And we're going to deal with that bug in an upcoming lecture.

191
00:10:46,660 --> 00:10:47,380
‫See you there.

