﻿1
00:00:03,980 --> 00:00:05,900
‫Hello and welcome back.

2
00:00:05,930 --> 00:00:10,610
‫Now we've created a tank that can move around and even rotate its turret.

3
00:00:10,610 --> 00:00:16,190
‫And we're ready now to create a tower class that can inherit some of the functionality that the tank

4
00:00:16,190 --> 00:00:18,830
‫inherited from the base pod class.

5
00:00:19,100 --> 00:00:24,560
‫Now, once we've created a tower class, we're going to override the tick function so that we can rotate

6
00:00:24,560 --> 00:00:26,000
‫its turret as well.

7
00:00:26,030 --> 00:00:32,080
‫So our goal here is to have the turrets rotate so that they're always looking at the tank.

8
00:00:32,090 --> 00:00:37,430
‫This way, when they start firing projectiles, they'll hit the tank sometimes as long as the tank isn't

9
00:00:37,430 --> 00:00:39,020
‫moving out of the way quickly.

10
00:00:39,630 --> 00:00:43,740
‫And we're also going to figure out how we can get a hold of the tank --.

11
00:00:43,770 --> 00:00:49,380
‫That way we can target the tank -- and rotate the towers turret toward the tank --.

12
00:00:49,410 --> 00:00:52,350
‫We're getting ready for some projectile combat.

13
00:00:52,650 --> 00:00:58,200
‫So I'm here in the editor and I'm going to go into our tune tanks folder where the base -- and the

14
00:00:58,200 --> 00:00:59,910
‫tank classes are.

15
00:01:00,270 --> 00:01:04,650
‫Now, I'd like to create a tower class based on the base -- class.

16
00:01:04,770 --> 00:01:07,850
‫Now, the way we did this with the tank class was we right.

17
00:01:07,860 --> 00:01:14,430
‫Clicked on base -- and selected create C++ class derived from based upon an alternative way is to

18
00:01:14,430 --> 00:01:18,210
‫go to tools and select new C++ class.

19
00:01:18,540 --> 00:01:24,630
‫And from here we can click the tab that says all classes and search for base --.

20
00:01:24,750 --> 00:01:27,270
‫And here we see our base -- class.

21
00:01:27,480 --> 00:01:33,050
‫If I select this and click next, now I'll be creating a new class based on base --.

22
00:01:33,060 --> 00:01:38,910
‫I'm going to leave it in the same path as all our other C++ classes and I'm going to call this tower.

23
00:01:39,210 --> 00:01:41,070
‫So let's click Create Class.

24
00:01:41,610 --> 00:01:44,720
‫So here's my new tower age and Tower Dot.

25
00:01:44,790 --> 00:01:51,360
‫CP Now the first thing we need is the tick function because the tower is going to want to rotate its

26
00:01:51,360 --> 00:01:53,520
‫turret to face the --.

27
00:01:53,730 --> 00:01:56,640
‫So we're going to override the tick function here.

28
00:01:56,640 --> 00:02:03,930
‫So I'm going to make a new public section and we're going to type virtual void tick, which takes a

29
00:02:03,930 --> 00:02:07,560
‫float called Delta Time, and this is an override.

30
00:02:07,560 --> 00:02:14,100
‫Now we'll get into more detail about virtual and override in future videos, but we're essentially taking

31
00:02:14,100 --> 00:02:18,600
‫the inherited tick function and creating a new implementation for it.

32
00:02:18,600 --> 00:02:23,520
‫So let's take the tick function and implement it here in Tower CP.

33
00:02:23,550 --> 00:02:29,370
‫Now we need to prefix the tick function name with a tower and the double colons.

34
00:02:29,370 --> 00:02:34,950
‫And as always, it's a good idea to call super tick and we need to pass in Delta time.

35
00:02:34,950 --> 00:02:40,830
‫Now what I'd like to do here is rotate the tank turret so that the tower is threatening the tank and

36
00:02:40,830 --> 00:02:42,390
‫ready to fire projectiles.

37
00:02:42,390 --> 00:02:45,870
‫But I'd like to do this only if the tank is in range.

38
00:02:46,170 --> 00:02:52,620
‫Now, in order to know whether or not the tank is in range, we need to know the distance from the turret

39
00:02:52,620 --> 00:02:53,750
‫to the tank.

40
00:02:53,760 --> 00:02:57,510
‫Now, here's a little gizmo that represents the origin of the world.

41
00:02:57,510 --> 00:03:01,470
‫In other words, the point in space where X, Y and Z are zero.

42
00:03:01,470 --> 00:03:08,220
‫Now, when we talk about an actor's location, we're talking about the vector from the origin to that

43
00:03:08,220 --> 00:03:08,970
‫location.

44
00:03:08,970 --> 00:03:15,060
‫And we can always get that location vector using get actor location so we can get the location of one

45
00:03:15,060 --> 00:03:17,430
‫of the towers and the location of the tank.

46
00:03:17,430 --> 00:03:21,930
‫And if we know those two locations, we can calculate the distance between them.

47
00:03:21,930 --> 00:03:28,470
‫Now, we could do this with vector mathematics, but the F vector class has a function called dist,

48
00:03:28,470 --> 00:03:33,810
‫and this function takes to location vectors and what it returns is the distance between them.

49
00:03:33,810 --> 00:03:40,440
‫So here in the tower CP file, in the tick function, I'm going to write a couple of notes just so we

50
00:03:40,440 --> 00:03:41,940
‫know what we're supposed to do.

51
00:03:41,940 --> 00:03:52,890
‫First, we need to find the distance to the tank after that check to see if the tank is in range and

52
00:03:52,890 --> 00:03:58,170
‫if in range rotate turret toward tank.

53
00:03:59,070 --> 00:04:00,960
‫So we have some to dos here.

54
00:04:01,140 --> 00:04:05,820
‫Now, in order to find the distance to the tank, we need to get a hold of the tank.

55
00:04:05,850 --> 00:04:08,640
‫Now, a good place to do that is in Begin Play.

56
00:04:08,640 --> 00:04:13,350
‫So in addition to the tick function, let's go ahead and override Begin Play.

57
00:04:13,380 --> 00:04:17,580
‫Now notice in Tank H, begin play is in a protected section.

58
00:04:17,580 --> 00:04:21,210
‫We're going to keep it protected in the tower as well.

59
00:04:21,210 --> 00:04:27,870
‫So we'll place the protected section just under the public one and will implement begin play just under

60
00:04:27,870 --> 00:04:28,380
‫tick.

61
00:04:28,380 --> 00:04:35,580
‫So let's go to Tower Dot, CP, implement, begin play fully qualify the function name and as you probably

62
00:04:35,580 --> 00:04:38,670
‫guessed, we're calling Super Begin Play.

63
00:04:38,790 --> 00:04:44,310
‫Now in order to get the tank and store it in a variable, we need a variable of type tank.

64
00:04:44,310 --> 00:04:49,200
‫So we're going to place that here in Towers H in a private section.

65
00:04:49,200 --> 00:04:55,290
‫Now this is going to be an A tank, it's a pointer and we can simply call this tank.

66
00:04:55,290 --> 00:05:01,980
‫And in order to avoid having to include Tank H here, we can forward declare we've seen how important

67
00:05:01,980 --> 00:05:03,000
‫that can be.

68
00:05:03,360 --> 00:05:09,540
‫So now we have this tank pointer and if we can figure out how to access the tank, we can store it in

69
00:05:09,540 --> 00:05:11,970
‫our tank pointer here and begin play.

70
00:05:12,000 --> 00:05:18,510
‫The first thing I'm going to do is include Tank H, so that way we can actually use the type.

71
00:05:18,510 --> 00:05:20,580
‫So how do we access the tank?

72
00:05:20,580 --> 00:05:26,220
‫Well, here's the unreal engine documentation for a handy function called get player pawn.

73
00:05:26,310 --> 00:05:29,100
‫It exists in a gameplay statics.

74
00:05:29,160 --> 00:05:34,680
‫So since I have this open, I'm going to go ahead and copy the include for gameplay statics and take

75
00:05:34,680 --> 00:05:35,910
‫a look at the syntax.

76
00:05:35,910 --> 00:05:39,060
‫It has two inputs a world context object.

77
00:05:39,470 --> 00:05:42,950
‫We already know how to handle that and a player index.

78
00:05:42,950 --> 00:05:49,310
‫And as we saw for single player games like ours, the player index will always be player zero and that

79
00:05:49,310 --> 00:05:53,660
‫will allow us to access the pawn corresponding to player zero.

80
00:05:54,050 --> 00:05:57,650
‫So let's call this function here in Tower Dot CP.

81
00:05:57,680 --> 00:06:04,850
‫I'm going to paste in the include for you gameplay statics and in begin play I'm going to set tank equal

82
00:06:04,850 --> 00:06:12,290
‫to you gameplay statics get player -- for the world context object.

83
00:06:12,290 --> 00:06:17,910
‫I can pass in this and for the player index we can pass in zero.

84
00:06:17,930 --> 00:06:19,970
‫Now check out the red squiggly.

85
00:06:19,970 --> 00:06:26,120
‫It says A value of type a pawn cannot be assigned to an entity of type A tank.

86
00:06:26,150 --> 00:06:33,290
‫This is the same exact issue we ran into when we were attempting to call, get controller and store

87
00:06:33,320 --> 00:06:35,810
‫the result in an A player controller.

88
00:06:35,870 --> 00:06:42,200
‫A tank is a child of a pawn, so we can't store a parent type in a child pointer.

89
00:06:42,200 --> 00:06:43,370
‫We have to.

90
00:06:44,150 --> 00:06:46,060
‫You guessed it, we have to cast.

91
00:06:46,070 --> 00:06:51,830
‫So we're going to take the value return from this and put it inside of a cast function call.

92
00:06:51,830 --> 00:06:56,000
‫So we're going to say cast and we're casting to a tank.

93
00:06:56,000 --> 00:07:02,300
‫And what we're passing in to cast is going to be this call to get player pond.

94
00:07:02,300 --> 00:07:04,850
‫So let's put that right there in the parentheses.

95
00:07:04,850 --> 00:07:09,260
‫And after the cast we will have access to the tank.

96
00:07:09,380 --> 00:07:16,310
‫So now that we have access to the tank, we can find the distance to the tank and a distance is a float.

97
00:07:16,310 --> 00:07:20,240
‫So we can make a local float variable called distance.

98
00:07:20,600 --> 00:07:27,380
‫And what we're going to set it equal to is the result of calling the F vector static function dist.

99
00:07:27,410 --> 00:07:31,700
‫Now dist takes two input parameters of type F vector.

100
00:07:31,880 --> 00:07:34,850
‫Now we want the distance between two points in space.

101
00:07:34,850 --> 00:07:37,010
‫One is the tower location.

102
00:07:37,010 --> 00:07:43,190
‫We're in the tower class so we can call get actor location and that gives us the location of the tower.

103
00:07:43,190 --> 00:07:44,660
‫But what about the tank?

104
00:07:44,660 --> 00:07:50,870
‫Well, we can call tank, get actor location, and now we have the distance.

105
00:07:50,870 --> 00:07:56,450
‫Now the only issue is that we're using the tank pointer without first checking to make sure it isn't

106
00:07:56,450 --> 00:07:57,110
‫null.

107
00:07:57,290 --> 00:08:05,600
‫So we have to say if tank first and then we can take this function call and drag it right here inside

108
00:08:05,600 --> 00:08:06,860
‫the if statement.

109
00:08:06,860 --> 00:08:13,190
‫So if the tank is valid, then we can access its location with get actor location.

110
00:08:13,190 --> 00:08:14,030
‫Excellent.

111
00:08:14,030 --> 00:08:19,130
‫Since we're working in this if statement, I'm going to move these other comments here inside of it

112
00:08:19,130 --> 00:08:24,410
‫because we know we can't check to see if the tank is in range, if the tank isn't even valid.

113
00:08:24,590 --> 00:08:28,790
‫So I'd like to challenge you to rotate the turret towards the tank.

114
00:08:28,790 --> 00:08:33,020
‫Now, we only want to do this if the tank is in range, we have the distance.

115
00:08:33,020 --> 00:08:35,240
‫So now we need a fire range variable.

116
00:08:35,240 --> 00:08:40,490
‫So create a float called fire range in the tower class and expose this with you property.

117
00:08:40,490 --> 00:08:42,980
‫We'd like to be able to edit this from the editor.

118
00:08:43,010 --> 00:08:45,890
‫Now you're going to check to see if the tank is in range.

119
00:08:45,890 --> 00:08:50,630
‫If it is called rotate turret and rotate turret needs a look at target.

120
00:08:50,630 --> 00:08:53,180
‫You're going to pass in the tanks location.

121
00:08:53,180 --> 00:08:56,660
‫So pause the video and implement this behavior now.

122
00:09:00,030 --> 00:09:00,420
‫Okay.

123
00:09:00,420 --> 00:09:02,370
‫So we need a fire range variable.

124
00:09:02,370 --> 00:09:05,940
‫So here in Tower H, we have a private section.

125
00:09:05,940 --> 00:09:07,680
‫We're going to make a float.

126
00:09:08,340 --> 00:09:15,450
‫I'm going to call this fire range and I'm going to go ahead and initialize it to a value of, say,

127
00:09:15,450 --> 00:09:16,650
‫300 F.

128
00:09:16,650 --> 00:09:21,030
‫But we'll experiment with this because it's going to be a you property.

129
00:09:21,240 --> 00:09:22,860
‫So you property.

130
00:09:22,860 --> 00:09:29,070
‫And since I'd like all of the tanks to have the same fire range, I'm going to make this and it defaults

131
00:09:29,070 --> 00:09:29,910
‫only.

132
00:09:29,910 --> 00:09:33,270
‫So that way we can only edit it on the default blueprint.

133
00:09:33,300 --> 00:09:38,940
‫Now if you made yours edit anywhere or maybe edit instance only, that's totally fine.

134
00:09:38,940 --> 00:09:42,090
‫It's really a matter of preference and we can change it later.

135
00:09:42,090 --> 00:09:46,710
‫I'm going to give it a category as well and I'm going to call this category combat.

136
00:09:46,740 --> 00:09:50,820
‫Let's go into Tower CP and we have this next point here.

137
00:09:50,820 --> 00:09:57,120
‫Check to see if the tank is in range, which means we need to check to see if distance is less than

138
00:09:57,120 --> 00:09:59,160
‫or equal to fire range.

139
00:09:59,160 --> 00:10:04,860
‫We have less than or equal to and not just equal to, because from frame to frame, the distance may

140
00:10:04,860 --> 00:10:11,310
‫actually be greater than fire range, one frame and less than fire range the next frame completely passing

141
00:10:11,310 --> 00:10:11,970
‫fire range.

142
00:10:11,970 --> 00:10:15,870
‫So it may actually never become exactly equal to fire range.

143
00:10:15,870 --> 00:10:20,820
‫In fact, with floating point values, two floats being exactly equal is quite rare.

144
00:10:20,820 --> 00:10:26,640
‫So we have this if check and if we get to the inside of it, that means distance is less than or equal

145
00:10:26,640 --> 00:10:27,630
‫to fire range.

146
00:10:27,630 --> 00:10:33,120
‫The tank is now in range, which means this comment can be moved right there.

147
00:10:33,960 --> 00:10:41,190
‫Now, if in range, rotate the turret toward the tank, that means we're going to call the rotate turret

148
00:10:41,190 --> 00:10:42,180
‫function.

149
00:10:42,390 --> 00:10:45,690
‫That's our protected function that we put in base pod.

150
00:10:45,720 --> 00:10:51,060
‫Now rotate turret takes a look at target and we need the location of the tank.

151
00:10:51,060 --> 00:10:55,410
‫So that's going to be tank get actor location.

152
00:10:55,410 --> 00:11:02,010
‫And with that we are now calling rotate turret only if the tank is in range.

153
00:11:02,010 --> 00:11:05,040
‫So let's compile this and see how it works.

154
00:11:05,340 --> 00:11:12,030
‫So we're back here in the editor and what we need to do is go into blueprints, pawns and find a BP

155
00:11:12,030 --> 00:11:15,120
‫pawn turret and open full blueprint editor.

156
00:11:15,120 --> 00:11:22,170
‫Now up at the top right, we see parent class base pawn, but we want our parent class to be the tower

157
00:11:22,170 --> 00:11:27,930
‫so we can go to class settings, parent class and search for tower and select it.

158
00:11:27,960 --> 00:11:31,980
‫Now our pawn turret is based on the tower class.

159
00:11:31,980 --> 00:11:34,710
‫Now let's see what happens when we hit play.

160
00:11:35,070 --> 00:11:37,200
‫Okay, so I'm moving the tank around.

161
00:11:37,200 --> 00:11:40,560
‫We're not in range, so we don't see any movement from the towers.

162
00:11:40,560 --> 00:11:44,100
‫But if I get in range, look at that.

163
00:11:44,100 --> 00:11:47,970
‫Now they're following me around and it looks quite threatening.

164
00:11:48,120 --> 00:11:52,080
‫Now 300 units is not that far away.

165
00:11:52,080 --> 00:11:55,440
‫So what I'd like to do is edit that distance.

166
00:11:55,440 --> 00:12:00,840
‫So from here in BP Pawn Turret, I'm going to select BP Pond Turret self.

167
00:12:00,840 --> 00:12:02,850
‫And here's the combat section.

168
00:12:02,850 --> 00:12:06,840
‫I'm going to go ahead and set this to about 700.

169
00:12:07,890 --> 00:12:13,350
‫Now, if I hit play, I'll see that they won't be rotating while I'm moving back here.

170
00:12:13,350 --> 00:12:16,410
‫But as soon as I get in range, now they're looking at me.

171
00:12:18,180 --> 00:12:19,020
‫Perfect.

172
00:12:20,030 --> 00:12:23,120
‫So in summary, we have created the tower class.

173
00:12:23,120 --> 00:12:25,720
‫We now have an enemy for the tank.

174
00:12:25,730 --> 00:12:32,060
‫We also rotated the tower's turret toward the tank in the tick function and we're only doing so if the

175
00:12:32,060 --> 00:12:33,770
‫tank is in fire range.

176
00:12:33,770 --> 00:12:39,650
‫We also exposed the fire range variable so that it can be adjusted in the blueprint.

177
00:12:39,770 --> 00:12:41,600
‫We're almost ready for combat.

178
00:12:41,630 --> 00:12:44,450
‫We'll start setting that up in the videos to come.

179
00:12:44,630 --> 00:12:45,620
‫I'll see you soon.

