﻿1
00:00:04,170 --> 00:00:04,650
‫Hey.

2
00:00:04,650 --> 00:00:05,610
‫Welcome back.

3
00:00:05,640 --> 00:00:11,010
‫Now we have our projectile, and we know that it's generating hit events, so we need to do something

4
00:00:11,010 --> 00:00:14,250
‫when the projectile actually hits our target.

5
00:00:14,280 --> 00:00:19,200
‫Now, that's going to involve doing damage, which means we need a way to keep track of health.

6
00:00:19,200 --> 00:00:24,840
‫So we're going to create a class for handling health and damage called a health component.

7
00:00:24,930 --> 00:00:30,720
‫And the reason this functionality gets its own class is so that we can reuse it for different classes

8
00:00:30,720 --> 00:00:32,690
‫such as the tank and the tower.

9
00:00:32,700 --> 00:00:35,250
‫So let's discuss this health component.

10
00:00:35,640 --> 00:00:38,900
‫Now we're familiar with the use scene component class.

11
00:00:38,910 --> 00:00:43,390
‫Well, this class is derived from a class called you actor component.

12
00:00:43,410 --> 00:00:47,220
‫In fact, here's the use scene component documentation.

13
00:00:47,220 --> 00:00:53,100
‫And in the inheritance hierarchy, you can see that it's parent is you actor component.

14
00:00:53,130 --> 00:00:57,330
‫Now the you act a component is more basic than the you seen component.

15
00:00:57,420 --> 00:00:59,070
‫It has no transform.

16
00:00:59,070 --> 00:01:05,020
‫So location, rotation and scale is not something that the you actor component even has.

17
00:01:05,040 --> 00:01:06,930
‫It doesn't support attachment.

18
00:01:06,930 --> 00:01:12,660
‫You can't attach an active component to, say, a static mesh component or a capsule component.

19
00:01:12,660 --> 00:01:15,180
‫It's just something that belongs to the actor.

20
00:01:15,180 --> 00:01:20,910
‫And because there's no visual representation or transform, we don't need to attach it to anything.

21
00:01:21,000 --> 00:01:27,060
‫Compare this to the use scene component, which actually does have a transform and the ability to attach

22
00:01:27,060 --> 00:01:31,640
‫itself to other components or have other components attach themselves to it.

23
00:01:31,650 --> 00:01:36,450
‫So to keep track of health and take care of damage, we don't need any of those things.

24
00:01:36,450 --> 00:01:39,990
‫So you act a component is going to be perfect for this.

25
00:01:40,170 --> 00:01:44,880
‫So let's hop back here into the editor and make our new act a component class.

26
00:01:44,880 --> 00:01:48,690
‫So we'll go up to tools and new C++ class.

27
00:01:48,690 --> 00:01:51,890
‫And if I scroll down, I can see actor component.

28
00:01:51,900 --> 00:01:53,730
‫This is what we're going to select.

29
00:01:53,760 --> 00:01:54,630
‫Now be careful.

30
00:01:54,630 --> 00:01:56,400
‫Don't select actor.

31
00:01:56,400 --> 00:01:57,750
‫That's a different class.

32
00:01:57,750 --> 00:02:02,610
‫It's actually a bigger class and has a lot more things than the actor component has.

33
00:02:02,610 --> 00:02:07,560
‫We need actor component specifically, so select that, click next.

34
00:02:07,560 --> 00:02:11,490
‫And this we can call simply Health Component.

35
00:02:11,880 --> 00:02:13,740
‫Let's click Create Class.

36
00:02:14,190 --> 00:02:21,420
‫Now here we have our new health components and CP files and you can see here that you health component,

37
00:02:21,420 --> 00:02:25,980
‫the class we just created is derived from you act a component.

38
00:02:25,980 --> 00:02:30,390
‫So make sure you have the correct type here and you'll see that it has in its U.

39
00:02:30,390 --> 00:02:31,710
‫Class macro.

40
00:02:31,740 --> 00:02:36,360
‫This meta specifies where and it says blueprints spawn table component.

41
00:02:36,360 --> 00:02:41,790
‫This is what's going to allow us to add this component directly in blueprints, which is what we're

42
00:02:41,790 --> 00:02:43,050
‫going to do now.

43
00:02:43,050 --> 00:02:48,960
‫The new health component is going to take care of health, which means we need a couple of variables.

44
00:02:48,960 --> 00:02:52,380
‫Let's go ahead and add these and I'm going to make them private.

45
00:02:52,380 --> 00:02:58,500
‫So let's go ahead and add a private section just under the protected one, and we can add a couple of

46
00:02:58,500 --> 00:02:59,700
‫health variables.

47
00:02:59,700 --> 00:03:04,290
‫Now, these are going to be floats and I'm going to call the first one Max Health.

48
00:03:04,320 --> 00:03:10,440
‫This will be the maximum amount of health that we can have and we can set this to a default value such

49
00:03:10,440 --> 00:03:12,180
‫as 100 F.

50
00:03:12,180 --> 00:03:18,000
‫Now, in addition to Max health, we're going to have a health value which will be the current health

51
00:03:18,000 --> 00:03:20,850
‫and this will be what changes as we take damage.

52
00:03:20,850 --> 00:03:24,720
‫So let's make another float and simply call this one health.

53
00:03:24,720 --> 00:03:30,900
‫Now we can initialize health to zero F and then set its value and begin play.

54
00:03:30,900 --> 00:03:37,380
‫And the reason we'll do that is because Max Health is going to have its own you property allowing us

55
00:03:37,380 --> 00:03:39,690
‫to set it from within the details panel.

56
00:03:39,690 --> 00:03:43,470
‫So let's give this a U property and make it edit anywhere.

57
00:03:43,680 --> 00:03:46,500
‫That way we can change it as we're developing.

58
00:03:46,500 --> 00:03:53,700
‫And then in health components CP here and begin play, we can simply set health equal to the value of

59
00:03:53,700 --> 00:03:54,600
‫max health.

60
00:03:54,600 --> 00:04:00,390
‫So that way when the game starts, health will have the value of max health even after we've changed

61
00:04:00,390 --> 00:04:01,860
‫it in the details panel.

62
00:04:02,040 --> 00:04:09,420
‫Okay, so let's compile this and back here in the editor, I'm going to open BP -- tank and open the

63
00:04:09,420 --> 00:04:10,920
‫full blueprint editor.

64
00:04:10,920 --> 00:04:16,200
‫And now I can add this health component here in the components panel.

65
00:04:16,290 --> 00:04:20,130
‫So I'm going to click Add and Search for Health.

66
00:04:20,370 --> 00:04:22,350
‫And here we see health.

67
00:04:22,530 --> 00:04:25,860
‫Now, we called it health component in C++.

68
00:04:25,860 --> 00:04:29,670
‫And in fact, the pop up shows that it's called health component.

69
00:04:29,670 --> 00:04:33,420
‫So it strips away that component part when showing it here.

70
00:04:33,420 --> 00:04:38,220
‫And you may have noticed that when you look for static mesh components or capsule components, you don't

71
00:04:38,220 --> 00:04:40,890
‫see the word component here either for those.

72
00:04:40,890 --> 00:04:48,270
‫So click on health and now we have our health component and you'll see that under health component we

73
00:04:48,270 --> 00:04:55,080
‫have max health and it's set to 100 and we don't see health because we didn't expose that variable.

74
00:04:55,170 --> 00:05:02,430
‫So now BP -- tank has a health component and it said that the tank owns this health component, the

75
00:05:02,430 --> 00:05:03,390
‫BP -- tank.

76
00:05:03,860 --> 00:05:06,590
‫Is the owner of this health component.

77
00:05:06,620 --> 00:05:13,760
‫Let's compile and save and close and open BP pawn turret and open the full blueprint editor and we can

78
00:05:13,760 --> 00:05:16,930
‫add a health component to the pond turret as well.

79
00:05:16,940 --> 00:05:21,620
‫So let's click add components, search for health and select health.

80
00:05:21,620 --> 00:05:25,490
‫And now we have a health component on the tower as well.

81
00:05:25,670 --> 00:05:30,560
‫So I'm going to compile and save these close out and save all.

82
00:05:30,590 --> 00:05:36,650
‫So we now have a health component and we mentioned that we'd like to have a health component so that

83
00:05:36,650 --> 00:05:38,740
‫we can reuse it with different classes.

84
00:05:38,750 --> 00:05:44,330
‫So if we have a pawn in the world, say, our tower, it's going to have its own health component and

85
00:05:44,330 --> 00:05:47,040
‫then our tank can have its own health component.

86
00:05:47,060 --> 00:05:52,340
‫Now, when our projectile interacts with either one of these, for example, when it generates a hit

87
00:05:52,340 --> 00:05:57,680
‫event, when hitting one of these things, then our pawns can trigger some functionality in the health

88
00:05:57,680 --> 00:06:00,830
‫component and change those health values.

89
00:06:00,830 --> 00:06:07,820
‫Putting our health functionality in a component and then adding that component to a class has some advantages

90
00:06:07,820 --> 00:06:13,760
‫over the alternative, which would be to simply place the health functionality in the base pawn class,

91
00:06:13,760 --> 00:06:17,520
‫for example, and inheriting that in the tank and tower.

92
00:06:17,540 --> 00:06:25,280
‫You see, this allows us to keep our tank and tower classes small and only deal with specified functionality

93
00:06:25,280 --> 00:06:26,420
‫for those classes.

94
00:06:26,420 --> 00:06:32,840
‫Whereas the health component can be added to any other actor, such as things that don't act like tanks

95
00:06:32,840 --> 00:06:33,800
‫or towers.

96
00:06:33,800 --> 00:06:39,290
‫We can make a destructible wall, for example, which could get destroyed as soon as it takes enough

97
00:06:39,290 --> 00:06:39,950
‫damage.

98
00:06:39,950 --> 00:06:43,910
‫So let's talk a little bit about how we can make this happen now.

99
00:06:43,910 --> 00:06:50,810
‫Unreal Engine has built in damage functionality and its damaged system is actually quite sophisticated.

100
00:06:50,810 --> 00:06:58,490
‫Any actor in our game inherits a number of damage events, one of which is called on take any damage.

101
00:06:58,490 --> 00:07:03,440
‫This is a multicast delegate, just like on component hit.

102
00:07:03,470 --> 00:07:08,360
‫Now we're going to add health components to our pawns and these will be based on our U.

103
00:07:08,360 --> 00:07:09,860
‫Health component class.

104
00:07:09,860 --> 00:07:16,550
‫So since we know that our pawns are going to inherit this on take any damage delegate, then if we create

105
00:07:16,550 --> 00:07:22,640
‫our own custom function in the health component class, then we can use this function as a callback

106
00:07:22,640 --> 00:07:25,940
‫and bind it to the on take any damage delegate.

107
00:07:25,940 --> 00:07:33,200
‫So then whenever a damage event gets generated, the on take any damage delegate can broadcast and any

108
00:07:33,200 --> 00:07:37,460
‫functions bound to it in its invocation list will be called.

109
00:07:37,460 --> 00:07:42,320
‫So the next question is how do we actually get that delegate to broadcast?

110
00:07:42,320 --> 00:07:45,080
‫We need a way to generate a damage event.

111
00:07:45,080 --> 00:07:52,070
‫Well, there's a function in your gameplay statics that will do just that and it's called apply damage.

112
00:07:52,070 --> 00:07:58,550
‫If we use this static function from your gameplay statics to apply damage, apply damage takes a number

113
00:07:58,550 --> 00:08:02,180
‫of parameters, including the actor that's getting damaged.

114
00:08:02,180 --> 00:08:09,620
‫So if we call apply damage the actors on take any damage delegate will be fired and that callback function

115
00:08:09,620 --> 00:08:11,720
‫will be called in response.

116
00:08:11,720 --> 00:08:15,830
‫So apply damage is what generates the damage event.

117
00:08:15,830 --> 00:08:19,520
‫So to set all of this up, we have three steps.

118
00:08:19,520 --> 00:08:25,760
‫First, create a callback function and since this will be bound to on take any damage, it must have

119
00:08:25,760 --> 00:08:31,550
‫the correct input parameters so that on take any damage will call it and pass in all of the associated

120
00:08:31,550 --> 00:08:33,950
‫information about the damage event.

121
00:08:34,130 --> 00:08:37,970
‫Step two is to bind this callback to the delegate.

122
00:08:38,000 --> 00:08:43,850
‫We've seen how to do this with the on component hit delegate using the add dynamic function.

123
00:08:43,850 --> 00:08:45,530
‫We'll be doing the same thing here.

124
00:08:45,530 --> 00:08:52,000
‫And the third step is to generate the damage event by calling the you game play static function, applied

125
00:08:52,010 --> 00:08:52,670
‫damage.

126
00:08:52,670 --> 00:08:56,210
‫So let's hop back into code and start setting this up.

127
00:08:56,600 --> 00:08:56,880
‫Okay.

128
00:08:56,960 --> 00:09:01,910
‫So we're here in health component and we're going to add a callback function.

129
00:09:01,910 --> 00:09:05,810
‫Now, this can be void and we can call it anything we like.

130
00:09:05,960 --> 00:09:08,450
‫I'm going to call this damage taken.

131
00:09:08,450 --> 00:09:14,870
‫And because we're binding this to a delegate, it has to have the correct input parameters appropriate

132
00:09:14,870 --> 00:09:16,280
‫for that delegate.

133
00:09:16,310 --> 00:09:23,240
‫Now for functions bound to the on take any damage delegate, the input parameter list has to be as follows.

134
00:09:23,240 --> 00:09:30,830
‫The first is an a actor pointer called Damaged Actor, and this is what it sounds like.

135
00:09:30,830 --> 00:09:33,320
‫It's the actor taking the damage.

136
00:09:33,350 --> 00:09:38,480
‫Next is a float called damage and this is the actual damage amount.

137
00:09:38,510 --> 00:09:45,950
‫Now, next, we have a cost you damage type pointer called damage type.

138
00:09:46,220 --> 00:09:52,430
‫And the reason we have this input parameter is because Unreal Engine has the concept of damage types.

139
00:09:52,430 --> 00:09:59,090
‫You can create custom damage types that have extra data that can inform you to do different things depending

140
00:09:59,090 --> 00:10:01,100
‫on the type of damage you may have.

141
00:10:01,100 --> 00:10:02,000
‫Fire damage.

142
00:10:02,000 --> 00:10:03,260
‫Poison damage.

143
00:10:03,320 --> 00:10:05,570
‫Explosive damage and so on.

144
00:10:05,570 --> 00:10:11,330
‫And if you want to implement custom functionality for each damage type, then you would implement that

145
00:10:11,330 --> 00:10:13,430
‫in your own custom damage type.

146
00:10:13,460 --> 00:10:19,040
‫Now we're not creating our own custom damage type, but because we're binding this function to the on

147
00:10:19,040 --> 00:10:22,940
‫take any damage delegate, it has to have these input parameters.

148
00:10:22,940 --> 00:10:24,380
‫So we're including it here.

149
00:10:24,410 --> 00:10:32,090
‫Now the next parameter is an A controller pointer and this is called instigator and the Unreal Engine

150
00:10:32,090 --> 00:10:33,330
‫Damage System.

151
00:10:33,350 --> 00:10:38,050
‫An instigator is the controller responsible for the damage.

152
00:10:38,060 --> 00:10:45,110
‫So if the damage was ultimately caused by a player controlling a pawn, then the instigator is the controller

153
00:10:45,110 --> 00:10:46,820
‫that's possessing that pawn.

154
00:10:46,850 --> 00:10:49,600
‫Now, there doesn't always need to be an instigator.

155
00:10:49,610 --> 00:10:52,580
‫If there was none, then this would simply be null.

156
00:10:52,580 --> 00:10:59,510
‫And now I'm getting the red squiggles so I can forward declare the A controller class here in the parentheses

157
00:10:59,510 --> 00:11:00,410
‫for the function.

158
00:11:00,440 --> 00:11:06,980
‫Now the last parameter is an A actor pointer and this one is called Damage Causer.

159
00:11:07,010 --> 00:11:10,370
‫This is the actual actor causing the damage.

160
00:11:10,370 --> 00:11:13,220
‫This would be the projectile itself.

161
00:11:13,310 --> 00:11:20,670
‫So we've declared this damage taken callback function and just like our other callback function on hit.

162
00:11:20,690 --> 00:11:22,970
‫This has to be a u function.

163
00:11:22,970 --> 00:11:28,550
‫So we're going to give it the function macro just to make sure that it works once we bind it to the

164
00:11:28,550 --> 00:11:30,620
‫on take any damage delegate.

165
00:11:30,950 --> 00:11:35,680
‫And now that we've declared it, we're ready to define it in the CPP file.

166
00:11:35,690 --> 00:11:38,540
‫So here in health components, CPP.

167
00:11:38,630 --> 00:11:45,530
‫Down at the bottom, I'm going to go ahead and give this a function body and fully qualify the function

168
00:11:45,530 --> 00:11:46,970
‫with the class name.

169
00:11:46,970 --> 00:11:49,400
‫And now we have a callback.

170
00:11:49,400 --> 00:11:52,400
‫So now we need to bind this to the delegate.

171
00:11:52,400 --> 00:11:59,180
‫But the delegate doesn't exist on the health component, it exists on actors specifically.

172
00:11:59,180 --> 00:12:05,970
‫We want to bind this to the on take any damage delegate in the pawn that owns this component.

173
00:12:05,990 --> 00:12:11,570
‫So how do we access the owner of this component so we can bind to one of its delegates?

174
00:12:11,570 --> 00:12:17,270
‫Well, we would do this and begin play and the way we can access the owner of a component is through

175
00:12:17,270 --> 00:12:19,460
‫the git owner function.

176
00:12:19,460 --> 00:12:23,530
‫If you hover over this, you'll see that it returns an a actor pointer.

177
00:12:23,540 --> 00:12:27,620
‫This is the pointer to the actor that owns a component.

178
00:12:27,620 --> 00:12:32,990
‫Components can be owned by pawns, they can be owned by actors, so it will return the owner in the

179
00:12:32,990 --> 00:12:35,630
‫form of an actor pointer.

180
00:12:35,810 --> 00:12:42,890
‫So we have our callback function and our second step is to bind it to the delegate on take any damage

181
00:12:42,890 --> 00:12:46,640
‫that's going to exist on the pawn that owns the health component.

182
00:12:46,790 --> 00:12:53,870
‫So since you have experience binding callbacks to delegates, this will be your challenge in the health

183
00:12:53,870 --> 00:12:55,100
‫component class.

184
00:12:55,100 --> 00:13:02,420
‫In Begin Play, you're going to bind damage taken to the on take any damage delegate that exists on

185
00:13:02,420 --> 00:13:04,190
‫the owner of the component.

186
00:13:04,190 --> 00:13:08,090
‫So you're going to access that delegate through the get owner function.

187
00:13:08,090 --> 00:13:13,640
‫In other words, you're going to call get owner and from that you're going to access on take any damage.

188
00:13:13,640 --> 00:13:20,660
‫And then from there you know how to bind callbacks to delegates using add dynamic if you get stuck look

189
00:13:20,660 --> 00:13:28,250
‫in how we bound the on hit callback to the on component hit delegate pause the video and bind damage

190
00:13:28,250 --> 00:13:31,790
‫taken to the on take any damage delegate now.

191
00:13:35,000 --> 00:13:35,360
‫Okay.

192
00:13:35,360 --> 00:13:40,610
‫So we're back here in health component and we're ready to do the binding of our callback function.

193
00:13:40,610 --> 00:13:47,390
‫So here and begin play, we're going to access the owner using the git owner function and from there

194
00:13:47,390 --> 00:13:54,770
‫we're going to use the arrow operator to access that delegate called on, take any damage and on take

195
00:13:54,770 --> 00:14:01,520
‫any damage has the add dynamic function and it simply takes a user object and a function name.

196
00:14:01,520 --> 00:14:05,240
‫Now the user object is the object we're binding the function for.

197
00:14:05,240 --> 00:14:10,130
‫It's the class that has the callback function on it and that's going to be this.

198
00:14:10,190 --> 00:14:14,420
‫And finally we have our callback function, which is going to be you.

199
00:14:14,420 --> 00:14:16,790
‫Health component damage taken.

200
00:14:16,790 --> 00:14:23,690
‫Now we need to remember the address of operator because this actually takes an address of the function.

201
00:14:23,690 --> 00:14:31,460
‫So now damage taken is bound to on take any damage and it's added to that delegate's invocation list.

202
00:14:31,460 --> 00:14:37,790
‫So whenever we generate damage events, we will get a broadcast from this delegate which will result

203
00:14:37,790 --> 00:14:40,970
‫in the damage taking function, getting called.

204
00:14:41,570 --> 00:14:48,320
‫So in summary, we've created our very own health component and we added one of these to both the tank

205
00:14:48,320 --> 00:14:50,540
‫blueprint and the tower blueprint.

206
00:14:50,660 --> 00:14:58,130
‫We created a callback function called Damage Taken and we bound it to the on take any damage delegate.

207
00:14:58,130 --> 00:15:05,150
‫The next step is to generate a damage event which will result in broadcasting the on take any damage

208
00:15:05,150 --> 00:15:10,640
‫delegate so that our callback function damage taken will get called in response.

209
00:15:10,640 --> 00:15:13,520
‫And we'll set that up in the next video.

210
00:15:14,240 --> 00:15:15,140
‫I'll see you soon.

