﻿1
00:00:04,480 --> 00:00:05,530
‫Welcome back.

2
00:00:05,560 --> 00:00:08,760
‫Now in this video, we're going to talk about hit events.

3
00:00:08,770 --> 00:00:15,430
‫We would like to detect when the projectile hits something and that way we can do something in response,

4
00:00:15,430 --> 00:00:17,560
‫such as destroy the projectile.

5
00:00:17,560 --> 00:00:22,710
‫And later we'll handle doing damage and causing explosion effects and things like that.

6
00:00:22,720 --> 00:00:26,350
‫So let's talk a little bit about hit events now.

7
00:00:26,350 --> 00:00:29,440
‫Our projectile has a mesh component.

8
00:00:29,440 --> 00:00:37,450
‫It's type is you static mesh component and you static mesh component is one class in a long hierarchy

9
00:00:37,450 --> 00:00:43,990
‫of classes and the unreal engine system one of its parents is you primitive component.

10
00:00:44,260 --> 00:00:48,100
‫Here is the documentation page for you primitive component.

11
00:00:48,130 --> 00:00:54,910
‫It says you primitive components are seen components that contain or generate some sort of geometry

12
00:00:54,910 --> 00:00:58,600
‫generally to be rendered or used as collision data.

13
00:00:58,600 --> 00:01:02,560
‫So they're basically scene components with some added features.

14
00:01:02,560 --> 00:01:08,440
‫And if you scroll down and look at the hierarchy, you'll see that we have you seen component and derived

15
00:01:08,440 --> 00:01:15,100
‫from that you primitive component and you can keep scrolling down and see all of the other classes that

16
00:01:15,100 --> 00:01:16,510
‫derive from you.

17
00:01:16,510 --> 00:01:17,860
‫Primitive component.

18
00:01:18,250 --> 00:01:24,280
‫Now the reason we're pointing this out is because you static mesh component inherits these features

19
00:01:24,280 --> 00:01:30,820
‫from you primitive component and you primitive component has the ability to generate hit events.

20
00:01:30,850 --> 00:01:33,670
‫Now, what do we mean by generate hit events?

21
00:01:33,760 --> 00:01:39,310
‫Well, let's say we have some geometry in our world represented by the rectangle to the right, and

22
00:01:39,310 --> 00:01:45,160
‫we have an object with a static mesh component represented by the circle to the left.

23
00:01:45,190 --> 00:01:52,660
‫Now, if this object that has a static mesh component is moving towards the block, then if this component

24
00:01:52,660 --> 00:01:58,630
‫is set up to handle hit events, then as soon as it hits that block, the hit event will be generated

25
00:01:58,630 --> 00:01:59,800
‫upon collision.

26
00:01:59,800 --> 00:02:06,040
‫Now a hit event will generate some data pertaining to that collision, including the component that

27
00:02:06,040 --> 00:02:06,640
‫was hit.

28
00:02:06,640 --> 00:02:09,640
‫So this block here may have a static mesh component.

29
00:02:09,640 --> 00:02:12,910
‫We can access that component upon colliding.

30
00:02:12,910 --> 00:02:19,120
‫We can also access the actor that was hit and the head event also generates an EF hit result.

31
00:02:19,120 --> 00:02:25,090
‫We've learned a little bit about the F hit result and we know that it contains lots of variables about

32
00:02:25,090 --> 00:02:30,790
‫the hit event, such as the hit location, which is an F vector representing a location in the world.

33
00:02:31,090 --> 00:02:33,460
‫So we have our projectile mesh.

34
00:02:33,460 --> 00:02:37,690
‫This is a variable of type you static mesh component pointer.

35
00:02:37,690 --> 00:02:43,000
‫Now whenever this static mesh component hits something in the world, we want to have some code that

36
00:02:43,000 --> 00:02:44,380
‫responds to that.

37
00:02:44,380 --> 00:02:50,740
‫Now being a static mesh component, it inherits things from the you primitive component class.

38
00:02:50,740 --> 00:02:55,450
‫One of the things it inherits is a variable called on component hit.

39
00:02:55,480 --> 00:02:58,750
‫Now here's the documentation for on component hit.

40
00:02:58,750 --> 00:03:05,320
‫It's described as an event called When a Component Hits or is hit by something solid.

41
00:03:05,320 --> 00:03:11,680
‫Now scrolling down, we see that on component hit has the type F component hit signature.

42
00:03:11,680 --> 00:03:17,770
‫And if we click on this, we see that F component hit signature is a struct.

43
00:03:17,800 --> 00:03:24,100
‫Now going back, we can see that the documentation says an event called when a component hits or is

44
00:03:24,100 --> 00:03:25,660
‫hit by something solid.

45
00:03:25,660 --> 00:03:32,140
‫This could happen due to things like character movement using set location with sweep enabled or physics

46
00:03:32,140 --> 00:03:38,920
‫simulation for events when objects overlap such as walking into a trigger, see the overlap event.

47
00:03:38,920 --> 00:03:42,280
‫So there are hit events and there are overlap events.

48
00:03:42,280 --> 00:03:44,230
‫We're concerned with hit events.

49
00:03:44,470 --> 00:03:51,700
‫So we know that on component hit is described in the documentation as a hit event and we know that on

50
00:03:51,700 --> 00:03:56,410
‫component hit is a struct of type F component hit signature.

51
00:03:56,410 --> 00:03:57,550
‫So far so good.

52
00:03:57,550 --> 00:04:04,930
‫Now this hit event on component hit is also something we refer to as a multicast delegate.

53
00:04:04,960 --> 00:04:10,270
‫A multicast delegate can have multiple functions bound to it.

54
00:04:10,300 --> 00:04:14,200
‫There can be functions that exist on multiple classes.

55
00:04:14,200 --> 00:04:20,980
‫And if those functions get bound to this multicast delegate, then they're added to something called

56
00:04:20,980 --> 00:04:22,600
‫an invocation list.

57
00:04:22,600 --> 00:04:29,650
‫This is a list of functions to be called when this hit event tells them all to be called.

58
00:04:29,650 --> 00:04:35,500
‫We say that this hit event or multicast delegate broadcasts when something happens.

59
00:04:35,500 --> 00:04:43,000
‫So in the event that our projectile mesh hits something, then the delegate will broadcast to all classes

60
00:04:43,000 --> 00:04:46,660
‫that have a function bound to this delegate.

61
00:04:46,690 --> 00:04:53,440
‫As soon as that broadcast is sent, then all of these bound functions are called in response to the

62
00:04:53,440 --> 00:04:54,370
‫broadcast.

63
00:04:54,370 --> 00:04:57,580
‫This is a very powerful feature of Unreal Engine.

64
00:04:57,580 --> 00:05:03,610
‫It allows us to have this a thing called a delegate, which waits for an event such as a collision.

65
00:05:03,610 --> 00:05:03,970
‫And then.

66
00:05:04,100 --> 00:05:11,270
‫And the delegate will be broadcast, resulting in all bound functions called in response to the broadcast.

67
00:05:11,270 --> 00:05:15,930
‫Since multiple functions can be bound to this delicate, we call it multicast.

68
00:05:15,950 --> 00:05:21,090
‫It's broadcasting to multiple classes that have their functions bound to it.

69
00:05:21,110 --> 00:05:24,460
‫Now, how do we bind a function to this delegate?

70
00:05:24,470 --> 00:05:30,350
‫Well, on component hit has a number of functions that allow us to do this, one of which is called

71
00:05:30,350 --> 00:05:31,720
‫add dynamic.

72
00:05:31,730 --> 00:05:38,930
‫So when we call the ADD dynamic function, all we need to do is pass in two parameters the user object

73
00:05:38,930 --> 00:05:45,260
‫which we can use this for, and the callback function, which is the address of some function on our

74
00:05:45,260 --> 00:05:46,000
‫class.

75
00:05:46,010 --> 00:05:52,790
‫So once we access this on component hit delegate and call the add dynamic function, we can pass in

76
00:05:52,820 --> 00:05:54,770
‫the user object and the callback.

77
00:05:54,770 --> 00:06:00,140
‫And this will result in adding that callback to the hit events invocation list.

78
00:06:00,170 --> 00:06:07,280
‫Now on component hit, we'll broadcast this delegate resulting in any functions bound to it to be called.

79
00:06:07,280 --> 00:06:12,290
‫So in order to bind to this delegate, we need to create a callback function.

80
00:06:12,470 --> 00:06:18,290
‫So here's projectile and we'd like a callback function for the hit event.

81
00:06:18,290 --> 00:06:23,090
‫So let's create a private function here and it's going to be void.

82
00:06:23,150 --> 00:06:25,480
‫And I'm going to just simply call this on hit.

83
00:06:25,490 --> 00:06:30,820
‫We could call this anything we want, but on seems descriptive enough.

84
00:06:30,830 --> 00:06:36,890
‫Now this callback function has to have the correct signature for hit events, which means its input

85
00:06:36,890 --> 00:06:40,460
‫parameter list needs to be very specific.

86
00:06:40,460 --> 00:06:49,870
‫The first input parameter has to be of type you primitive component pointer and it's called hit comp.

87
00:06:49,880 --> 00:06:52,160
‫This is the component doing the hitting.

88
00:06:52,160 --> 00:06:56,170
‫In our case, we're going to have our projectile mesh hitting things.

89
00:06:56,180 --> 00:07:02,240
‫The next parameter is an a actor pointer called Other Actor.

90
00:07:02,540 --> 00:07:05,690
‫This is going to be the actor that got hit.

91
00:07:05,720 --> 00:07:12,950
‫The next input parameter is another you primitive component pointer called other comp.

92
00:07:12,980 --> 00:07:15,590
‫This is the other component that was hit.

93
00:07:15,590 --> 00:07:21,410
‫So if we hit the static mesh component of some other actor, then this would be that static mesh component.

94
00:07:21,410 --> 00:07:25,760
‫Next is an F vector called normal impulse.

95
00:07:25,820 --> 00:07:32,000
‫If we're simulating physics, the physics engine will apply an impulse in response to the collision.

96
00:07:32,000 --> 00:07:37,510
‫And this f vector represents the direction and the magnitude of that impulse.

97
00:07:37,520 --> 00:07:46,130
‫And finally, we have an input parameter of type const F hit result and this is a const reference and

98
00:07:46,130 --> 00:07:47,450
‫it's called hit.

99
00:07:47,450 --> 00:07:53,780
‫So when on hit gets called, we'll have access to a hit result that contains even more information about

100
00:07:53,780 --> 00:07:54,380
‫the hit.

101
00:07:54,410 --> 00:07:59,150
‫Now, since we're binding this to a delegate, it has to be a U function.

102
00:07:59,150 --> 00:08:01,940
‫So we're going to mark this with you function.

103
00:08:01,940 --> 00:08:03,800
‫Now, you should be familiar with you function.

104
00:08:03,800 --> 00:08:08,390
‫It's just like you property only it's for functions rather than variables.

105
00:08:08,390 --> 00:08:09,590
‫So very important.

106
00:08:09,590 --> 00:08:12,890
‫Our callback has to be a u function for this to work.

107
00:08:12,890 --> 00:08:14,600
‫Now we've declared the function.

108
00:08:14,600 --> 00:08:17,330
‫Let's go ahead and define the function.

109
00:08:17,570 --> 00:08:19,090
‫So back in projectiles.

110
00:08:19,160 --> 00:08:24,410
‫CP Just under our tick function, let's define this function.

111
00:08:24,410 --> 00:08:31,100
‫We'll give it a function body and put the class name just before the function name, and now we have

112
00:08:31,100 --> 00:08:32,240
‫a callback function.

113
00:08:32,510 --> 00:08:39,230
‫So we're ready to bind this on hit function to our delegate and we need to do this in begin play.

114
00:08:39,260 --> 00:08:44,450
‫Doing it in the constructor is to early and sometimes you can run into issues like your delegate not

115
00:08:44,450 --> 00:08:45,380
‫being bound.

116
00:08:45,380 --> 00:08:47,330
‫So we're going to do it here and begin play.

117
00:08:47,330 --> 00:08:55,220
‫So we have our projectile mesh and we'll use the arrow operator to access the variable inherited from

118
00:08:55,220 --> 00:08:55,460
‫you.

119
00:08:55,460 --> 00:09:03,470
‫Primitive component called on component hit and on component hit has the function add dynamic.

120
00:09:03,470 --> 00:09:08,300
‫Now strangely, autocomplete is not going to work for add dynamic, so you're going to have to type

121
00:09:08,300 --> 00:09:09,740
‫the entire function name.

122
00:09:09,740 --> 00:09:17,000
‫This is the function we'll use to bind our callback to on component hit and add that function to its

123
00:09:17,000 --> 00:09:18,410
‫invocation list.

124
00:09:18,410 --> 00:09:23,960
‫Now first, we need the user object that's going to be this because of this is the class where binding

125
00:09:23,960 --> 00:09:30,290
‫the function for and next we need the address to the function that's going to be the address of on hit.

126
00:09:30,290 --> 00:09:35,720
‫So we'll use the address of operator and the function a projectile on hit.

127
00:09:35,720 --> 00:09:41,180
‫And with this we have our function bound and we're ready to generate hit events.

128
00:09:41,420 --> 00:09:47,150
‫Now we can test this out with a UEE log and we can use log temp warning.

129
00:09:48,550 --> 00:09:52,120
‫And for the text we can simply say on hit.

130
00:09:52,270 --> 00:09:58,090
‫And if we see this in the output log, we know that our on hit function has been called let's compile

131
00:09:58,090 --> 00:09:58,570
‫this.

132
00:09:59,020 --> 00:10:01,270
‫So I have the output log open here.

133
00:10:01,270 --> 00:10:08,440
‫I'm going to press play and fire a projectile and there's my log message on hit is being called.

134
00:10:08,440 --> 00:10:09,730
‫So this is working.

135
00:10:10,450 --> 00:10:17,230
‫Now just a side note, if we go into BP projectile and select projectile mesh in the details panel,

136
00:10:17,230 --> 00:10:19,900
‫we can scroll down to the collision section.

137
00:10:20,080 --> 00:10:26,290
‫And here we see that the collision presets is set to block all dynamic and that collision enabled is

138
00:10:26,290 --> 00:10:30,760
‫set to this setting collision enabled query and physics.

139
00:10:30,760 --> 00:10:33,280
‫This is necessary for hit events.

140
00:10:33,280 --> 00:10:36,700
‫We need to be able to query for a hit event.

141
00:10:36,700 --> 00:10:41,800
‫And of course, physics allows the physics engine to act on the projectile mesh.

142
00:10:41,800 --> 00:10:48,700
‫So now that we've bound to the on component hit delegate with our on hit function and we've placed a

143
00:10:48,700 --> 00:10:55,000
‫huge log to make sure that it's working, I'd like you to explore this function a little bit more so

144
00:10:55,000 --> 00:10:59,440
‫that we can understand some of these input parameters in our on hit function.

145
00:10:59,440 --> 00:11:03,160
‫So in the on hit function, add some more YOUI logs.

146
00:11:03,160 --> 00:11:08,980
‫I'd like you to print the names of some of these input parameters using the git name function.

147
00:11:08,980 --> 00:11:15,970
‫I'd like you to use a YUI log to print the name of hit comp, other actor and other comp so that we

148
00:11:15,970 --> 00:11:18,340
‫could see the names of these objects we're hitting.

149
00:11:18,340 --> 00:11:23,770
‫You're going to use the percent se format, specify the in the E log text macro.

150
00:11:23,770 --> 00:11:30,700
‫And just as a reminder, whenever we call get name, we have to use the asterisk when passing that string

151
00:11:30,700 --> 00:11:36,880
‫into the YUI log macro, for example, to get the name of other actor we would call other actor, get

152
00:11:36,880 --> 00:11:42,590
‫name and place that asterisk at the beginning just to return that C style string, which is what you

153
00:11:42,670 --> 00:11:45,550
‫log expects when you format it with a string.

154
00:11:45,550 --> 00:11:52,330
‫So pause the video and use Yui log in our on hit function to print the names of hit comp, other actor

155
00:11:52,330 --> 00:11:53,890
‫and other comp now.

156
00:11:57,740 --> 00:11:58,040
‫Okay.

157
00:11:58,040 --> 00:12:02,570
‫So here in projectile CP, I'm going to use you log here.

158
00:12:02,720 --> 00:12:10,610
‫So I'm going to copy this line where I'm using Yui log and for the string I'm going to say hit comp

159
00:12:11,270 --> 00:12:20,000
‫percent s and just after the text I'm going to call hit comp get name and I need this asterisk to convert

160
00:12:20,000 --> 00:12:22,910
‫from an F string to a C style string.

161
00:12:22,910 --> 00:12:29,330
‫Now I'm going to use this same line, only I'm going to change the text to say other actor and we're

162
00:12:29,330 --> 00:12:32,480
‫calling it name this time on other actor.

163
00:12:32,600 --> 00:12:39,950
‫And finally, I'm going to print other comp calling, get name on other comp.

164
00:12:40,130 --> 00:12:46,250
‫So let's compile and back here in the editor, I'm going to go ahead and hit play and shoot a projectile

165
00:12:46,250 --> 00:12:47,630
‫and check this out.

166
00:12:47,660 --> 00:12:50,780
‫We see that hit comp is projectile mesh.

167
00:12:50,780 --> 00:12:56,180
‫Remember we said that this is the component doing the hitting, which is our projectile mash and you'll

168
00:12:56,180 --> 00:13:01,940
‫see that it's using the name that we assigned to this component in create default sub object.

169
00:13:01,940 --> 00:13:05,570
‫So this is one of those situations where that name is being used.

170
00:13:05,570 --> 00:13:09,830
‫Now you'll see that it says other actor flaw underscore zero.

171
00:13:09,830 --> 00:13:16,130
‫And that's because this static mesh actor that is the flaw has the name flaw underscore zero.

172
00:13:16,130 --> 00:13:22,160
‫Sometimes the engine will place a number at the end of its internal name for actors and components,

173
00:13:22,160 --> 00:13:26,630
‫and you'll see that we have that same thing happening when we print out other comp.

174
00:13:26,630 --> 00:13:33,110
‫The flaw static mesh actor has a static mesh component and its name is static mesh component zero.

175
00:13:33,110 --> 00:13:40,610
‫So this gives us a little bit more information about those input parameters in our on hit callback function.

176
00:13:40,610 --> 00:13:47,600
‫And this is useful because we have access to those objects in C++ if we'd like to do something in response

177
00:13:47,600 --> 00:13:48,620
‫to the hit event.

178
00:13:48,800 --> 00:13:56,210
‫So in summary, we have learned about hit events and how these are implemented as multicast delegates

179
00:13:56,210 --> 00:13:57,650
‫and we learned how those work.

180
00:13:57,650 --> 00:14:05,030
‫We created a function called On Hit and Bound, that function to the on component hit delegate that

181
00:14:05,030 --> 00:14:09,620
‫our projectile mesh has inherited from the you primitive component class.

182
00:14:09,620 --> 00:14:15,920
‫Now we haven't destroyed the projectile on hit, but we now know that we can easily do so because we

183
00:14:15,920 --> 00:14:21,860
‫have this callback function and we can place logic in this function such as destroying the projectile.

184
00:14:21,860 --> 00:14:24,080
‫So we'll handle that in a future video.

185
00:14:24,080 --> 00:14:30,800
‫For now, pat yourself on the back because this is one of the more complex areas of Unreal Engine C++

186
00:14:30,800 --> 00:14:32,270
‫that you've learned so far.

187
00:14:32,480 --> 00:14:33,890
‫I'll see you in the next video.

