﻿1
00:00:04,480 --> 00:00:05,530
‫欢迎回来｡

2
00:00:05,560 --> 00:00:08,760
‫在这段视频中, 我们将讨论热门事件｡

3
00:00:08,770 --> 00:00:17,560
‫我们希望探测到抛射体何时击中某物, 这样我们就可以做出反应, 比如摧毁抛射体｡

4
00:00:17,560 --> 00:00:22,710
‫稍后我们将处理造成破坏和造成爆炸效果之类的事情｡

5
00:00:22,720 --> 00:00:26,350
‫现在我们来谈谈热门事件｡

6
00:00:26,350 --> 00:00:29,440
‫我们的射弹有一个网状部件｡

7
00:00:29,440 --> 00:00:37,450
‫它的类型是你的静态网格组件, 你的静态网格组件是一个类的长层次结构中的一个类,

8
00:00:37,450 --> 00:00:43,990
‫而虚幻引擎系统的一个父级是你的原始组件｡

9
00:00:44,260 --> 00:00:48,100
‫下面是基本组件的文档页面｡

10
00:00:48,130 --> 00:00:58,600
‫它表示基本体组件是包含或生成某种几何体的可见组件, 这些几何体通常要渲染或用作碰撞数据｡

11
00:00:58,600 --> 00:01:02,560
‫因此, 它们基本上是添加了一些功能的场景组件｡

12
00:01:02,560 --> 00:01:08,440
‫如果你向下滚动查看层次结构,

13
00:01:08,440 --> 00:01:16,510
‫你会看到组件和派生自原始组件的类, 你可以继续向下滚动查看派生自原始组件的所有其他类｡

14
00:01:16,510 --> 00:01:17,860
‫基元组件｡

15
00:01:18,250 --> 00:01:24,280
‫我们指出这一点的原因是,

16
00:01:24,280 --> 00:01:30,820
‫静态网格组件从基本组件继承了这些功能, 并且基本组件能够生成命中事件｡

17
00:01:30,850 --> 00:01:33,670
‫现在, 我们所说的生成命中事件是什么意思？

18
00:01:33,760 --> 00:01:39,310
‫好吧, 让我们假设我们的世界中有一些几何体,

19
00:01:39,310 --> 00:01:45,160
‫用右边的矩形表示, 我们有一个对象, 它有一个静态网格组件, 用左边的圆表示｡

20
00:01:45,190 --> 00:01:52,660
‫现在, 如果这个具有静态网格组件的对象正在向块移动, 那么如果这个组件被设置为处理碰撞事件,

21
00:01:52,660 --> 00:01:59,800
‫那么一旦它碰撞到块, 碰撞事件就会生成｡

22
00:01:59,800 --> 00:02:06,640
‫现在, 碰撞事件将生成与该碰撞有关的一些数据, 包括被碰撞的组件｡

23
00:02:06,640 --> 00:02:09,640
‫因此, 这个块可能有一个静态网格组件｡

24
00:02:09,640 --> 00:02:12,910
‫我们可以在碰撞时访问该组件｡

25
00:02:12,910 --> 00:02:19,120
‫我们还可以访问被命中的演员, head事件也会生成EF命中结果｡

26
00:02:19,120 --> 00:02:25,090
‫我们已经了解了一些关于F命中结果的知识, 我们知道它包含了很多关于命中事件的变量, 比如命中位置,

27
00:02:25,090 --> 00:02:30,790
‫它是一个F向量, 代表了世界上的一个位置｡

28
00:02:31,090 --> 00:02:33,460
‫所以我们有了投射网｡

29
00:02:33,460 --> 00:02:37,690
‫这是一个静态网格组件指针类型的变量｡

30
00:02:37,690 --> 00:02:44,380
‫现在, 每当这个静态网格组件碰到世界上的某个东西时, 我们需要一些代码来响应｡

31
00:02:44,380 --> 00:02:50,740
‫现在, 作为一个静态网格组件, 它继承了原始组件类的内容｡

32
00:02:50,740 --> 00:02:55,450
‫它继承的东西之一是在组件命中时调用的变量｡

33
00:02:55,480 --> 00:02:58,750
‫下面是有关组件命中的文档｡

34
00:02:58,750 --> 00:03:05,320
‫它被描述为一个名为“当组件击中或被固体击中”的事件｡

35
00:03:05,320 --> 00:03:11,680
‫现在向下滚动, 我们看到on组件命中具有类型F组件命中签名｡

36
00:03:11,680 --> 00:03:17,770
‫如果我们点击它, 我们会看到F组件的命中签名是一个结构体｡

37
00:03:17,800 --> 00:03:25,660
‫现在回过头来, 我们可以看到文档中提到了一个事件, 当一个组件碰撞或被某个实体碰撞时, 该事件被调用｡

38
00:03:25,660 --> 00:03:32,140
‫这可能是由于以下原因造成的：使用启用扫描的设定位置的角色移动,

39
00:03:32,140 --> 00:03:38,920
‫或对象重叠时事件的物理模拟（如走进触发器）, 请参见重叠事件｡

40
00:03:38,920 --> 00:03:42,280
‫因此, 有命中事件和重叠事件｡

41
00:03:42,280 --> 00:03:44,230
‫我们关注的是热门事件｡

42
00:03:44,470 --> 00:03:51,700
‫我们知道on component hit在文档中被描述为hit事件, 并且我们知道on

43
00:03:51,700 --> 00:03:56,410
‫component hit是一个F类型的结构体｡

44
00:03:56,410 --> 00:03:57,550
‫目前为止一切顺利｡

45
00:03:57,550 --> 00:04:04,930
‫现在, 组件命中时的命中事件也被称为多播委托｡

46
00:04:04,960 --> 00:04:10,270
‫多点传送委派可以系结多个函式｡

47
00:04:10,300 --> 00:04:14,200
‫函数可以存在于多个类上｡

48
00:04:14,200 --> 00:04:22,600
‫如果这些函数被绑定到这个多播委托, 那么它们就被添加到一个叫做调用列表的东西中｡

49
00:04:22,600 --> 00:04:29,650
‫这是一个函数列表, 当这个hit事件告诉所有函数都被调用时, 这些函数将被调用｡

50
00:04:29,650 --> 00:04:35,500
‫我们说这个命中事件或多播委托在某件事发生时进行广播｡

51
00:04:35,500 --> 00:04:46,660
‫因此, 如果我们的投射网格击中了某个东西, 那么这个委托将广播给所有绑定了这个委托的函数的类｡

52
00:04:46,690 --> 00:04:54,370
‫一旦广播被发送, 那么所有这些绑定函数都被调用以响应广播｡

53
00:04:54,370 --> 00:04:57,580
‫这是Unreal Engine的一个非常强大的功能｡

54
00:04:57,580 --> 00:05:03,610
‫它允许我们有一个叫做代理的东西, 它等待一个事件, 比如碰撞｡

55
00:05:03,610 --> 00:05:03,970
‫然后就｡

56
00:05:04,100 --> 00:05:11,270
‫并且该委托将被广播, 从而导致响应广播而调用所有绑定函数｡

57
00:05:11,270 --> 00:05:15,930
‫由于多个功能可以绑定到这个微妙的, 我们称之为多播｡

58
00:05:15,950 --> 00:05:21,090
‫它向多个绑定了函数的类广播｡

59
00:05:21,110 --> 00:05:24,460
‫现在, 我们如何将一个函数绑定到这个委托？

60
00:05:24,470 --> 00:05:30,350
‫好的, on component hit有很多函数可以让我们做到这一点, 其中一个叫做add

61
00:05:30,350 --> 00:05:31,720
‫dynamic｡

62
00:05:31,730 --> 00:05:38,930
‫所以当我们调用ADD动态函数时, 我们需要做的就是传入两个参数, 一个是用户对象, 我们可以使用它,

63
00:05:38,930 --> 00:05:46,000
‫另一个是回调函数, 它是我们类中某个函数的地址｡

64
00:05:46,010 --> 00:05:54,770
‫因此, 一旦我们在组件命中委托上访问此对象并调用add动态函数, 我们就可以传入用户对象和回调｡

65
00:05:54,770 --> 00:06:00,140
‫这将导致将该回调添加到命中事件调用列表中｡

66
00:06:00,170 --> 00:06:07,280
‫现在, 在组件命中时, 我们将广播此委托, 从而调用绑定到它的任何函数｡

67
00:06:07,280 --> 00:06:12,290
‫所以为了绑定到这个委托, 我们需要创建一个回调函数｡

68
00:06:12,470 --> 00:06:18,290
‫这里有一个projectile, 我们想要一个hit事件的回调函数｡

69
00:06:18,290 --> 00:06:23,090
‫我们在这里创建一个私有函数, 它是空的.

70
00:06:23,150 --> 00:06:25,480
‫我只跟这个叫hit｡

71
00:06:25,490 --> 00:06:30,820
‫我们可以称之为任何我们想要的, 但似乎足够描述｡

72
00:06:30,830 --> 00:06:36,890
‫现在, 这个回调函数必须具有正确的hit事件签名,

73
00:06:36,890 --> 00:06:40,460
‫这意味着它的输入参数列表必须非常具体｡

74
00:06:40,460 --> 00:06:49,870
‫第一个输入参数必须是原始组件指针的类型, 它被称为hit comp｡

75
00:06:49,880 --> 00:06:52,160
‫这是执行撞击的组件｡

76
00:06:52,160 --> 00:06:56,170
‫在我们的例子中, 我们要让我们的投射网击中物体｡

77
00:06:56,180 --> 00:07:02,240
‫下一个参数是一个名为Other Actor的执行元指针｡

78
00:07:02,540 --> 00:07:05,690
‫这将是被击中的演员｡

79
00:07:05,720 --> 00:07:12,950
‫下一个输入参数是另一个你称为other comp的原语组件指针｡

80
00:07:12,980 --> 00:07:15,590
‫这是另一个被击中的部件｡

81
00:07:15,590 --> 00:07:21,410
‫所以如果我们碰到其他角色的静态网格组件, 那么这就是那个静态网格组件｡

82
00:07:21,410 --> 00:07:25,760
‫接下来是一个F向量, 称为法向脉冲｡

83
00:07:25,820 --> 00:07:32,000
‫如果我们在模拟物理, 物理引擎将应用一个脉冲来响应碰撞｡

84
00:07:32,000 --> 00:07:37,510
‫这个f矢量代表了这个脉冲的方向和大小｡

85
00:07:37,520 --> 00:07:47,450
‫最后, 我们有一个const F hit result类型的输入参数, 这是一个const引用, 它被称为hit｡

86
00:07:47,450 --> 00:07:54,380
‫因此, 当调用on hit时, 我们将可以访问一个hit结果, 其中包含有关该hit的更多信息｡

87
00:07:54,410 --> 00:07:59,150
‫现在, 因为我们要把它绑定到一个委托, 它必须是一个U函数｡

88
00:07:59,150 --> 00:08:01,940
‫所以我们要用函数来标记它｡

89
00:08:01,940 --> 00:08:03,800
‫现在, 您应该熟悉您的函数｡

90
00:08:03,800 --> 00:08:08,390
‫这就像你的属性一样, 只是它是针对函数而不是变量的｡

91
00:08:08,390 --> 00:08:09,590
‫所以非常重要｡

92
00:08:09,590 --> 00:08:12,890
‫我们的回调函数必须是一个u函数才能正常工作｡

93
00:08:12,890 --> 00:08:14,600
‫现在我们已经声明了函数｡

94
00:08:14,600 --> 00:08:17,330
‫让我们继续定义函数｡

95
00:08:17,570 --> 00:08:19,090
‫所以回到射弹｡

96
00:08:19,160 --> 00:08:24,410
‫在tick函数下面, 我们定义这个函数｡

97
00:08:24,410 --> 00:08:32,240
‫我们给予它一个函数体, 把类名放在函数名前面, 这样就有了一个回调函数｡

98
00:08:32,510 --> 00:08:39,230
‫我们已经准备好把这个on hit函数绑定到我们的委托上了, 我们需要在开始播放的时候做这个｡

99
00:08:39,260 --> 00:08:45,380
‫在构造函数中做这件事太早了, 有时你会遇到委托没有被绑定的问题｡

100
00:08:45,380 --> 00:08:47,330
‫所以我们要在这里开始｡

101
00:08:47,330 --> 00:08:55,460
‫我们有了投射网格, 我们将使用箭头操作符来访问从你那里继承的变量｡

102
00:08:55,460 --> 00:09:03,470
‫在组件命中时调用的基元组件和在组件命中时调用的基元组件具有函数add dynamic｡

103
00:09:03,470 --> 00:09:09,740
‫奇怪的是, 自动补全对add dynamic不起作用, 所以你必须输入完整的函数名｡

104
00:09:09,740 --> 00:09:18,410
‫我们将使用这个函数在组件命中时绑定回调, 并将该函数添加到其调用列表中｡

105
00:09:18,410 --> 00:09:23,960
‫首先, 我们需要一个用户对象,

106
00:09:23,960 --> 00:09:30,290
‫因为它是绑定函数的类, 接下来我们需要函数的地址, 它是on hit的地址.

107
00:09:30,290 --> 00:09:35,720
‫所以我们要用运算符的地址和函数a projectile on hit｡

108
00:09:35,720 --> 00:09:41,180
‫这样我们就有了函数绑定, 我们就可以生成hit事件了｡

109
00:09:41,420 --> 00:09:47,150
‫现在, 我们可以使用UEE日志对此进行测试, 还可以使用日志临时警告｡

110
00:09:48,550 --> 00:09:52,120
‫对于文本, 我们可以简单地说on hit｡

111
00:09:52,270 --> 00:09:58,570
‫如果我们在输出日志中看到这个, 我们就知道我们的on hit函数已经被调用了, 让我们编译它｡

112
00:09:59,020 --> 00:10:01,270
‫我在这里打开了输出日志｡

113
00:10:01,270 --> 00:10:08,440
‫我将按下播放键并发射一个炮弹, 这是我的日志消息, 正在调用命中｡

114
00:10:08,440 --> 00:10:09,730
‫这是有效的｡

115
00:10:10,450 --> 00:10:19,900
‫现在只是一个侧记, 如果我们进入BP抛射体并在细节面板中选择抛射体网格, 我们可以向下滚动到碰撞部分｡

116
00:10:20,080 --> 00:10:26,290
‫这里我们看到, 碰撞预设设置为阻止所有动态,

117
00:10:26,290 --> 00:10:30,760
‫碰撞启用设置为碰撞启用查询和物理｡

118
00:10:30,760 --> 00:10:33,280
‫这对于命中事件是必需的｡

119
00:10:33,280 --> 00:10:36,700
‫我们需要能够查询命中事件｡

120
00:10:36,700 --> 00:10:41,800
‫当然, 物理学允许物理引擎作用于抛射体网格｡

121
00:10:41,800 --> 00:10:48,700
‫现在我们已经用on hit函数绑定了on组件hit委托, 并且我们已经放置了一个很大的日志来确保它工作正常,

122
00:10:48,700 --> 00:10:55,000
‫我希望你能更深入地研究这个函数, 这样我们就能理解on

123
00:10:55,000 --> 00:10:59,440
‫hit函数中的一些输入参数｡

124
00:10:59,440 --> 00:11:03,160
‫因此, 在on hit函数中, 添加一些更多的YOUI日志｡

125
00:11:03,160 --> 00:11:08,980
‫我想让你用git name函数打印一些输入参数的名字｡

126
00:11:08,980 --> 00:11:18,340
‫我想让你用一个YUI日志来打印点击伴奏的名字, 其他演员和其他伴奏, 这样我们就可以看到我们正在点击的这些对象的名字｡

127
00:11:18,340 --> 00:11:23,770
‫您将使用百分比se格式, 请在E log文本宏中指定｡

128
00:11:23,770 --> 00:11:30,700
‫提醒一下, 每当我们调用get name时, 我们必须在将该字符串传递到YUI log宏时使用星号,

129
00:11:30,700 --> 00:11:36,880
‫例如, 要获取其他actor的名称, 我们将调用other actor,

130
00:11:36,880 --> 00:11:42,590
‫get name, 并将星号放在开头, 以返回C风格的字符串,

131
00:11:42,670 --> 00:11:45,550
‫这是log在使用字符串格式化时所期望的｡

132
00:11:45,550 --> 00:11:52,330
‫因此, 暂停视频, 并使用Yui登录我们的on hit功能, 打印hit comp的名称,

133
00:11:52,330 --> 00:11:53,890
‫其他演员和其他comp现在｡

134
00:11:57,740 --> 00:11:58,040
‫好吧, 我会的

135
00:11:58,040 --> 00:12:02,570
‫在这里, 在投射CP中, 我将使用日志｡

136
00:12:02,720 --> 00:12:10,610
‫我会复制这一行, 在这里我使用了Yui log, 对于字符串, 我会说hit comp

137
00:12:11,270 --> 00:12:20,000
‫percent, 就在文本后面, 我会调用hit comp get name, 我需要这个星号,

138
00:12:20,000 --> 00:12:22,910
‫把F字符串转换成C风格的字符串｡

139
00:12:22,910 --> 00:12:32,480
‫现在我将使用同样的语句, 只不过我将把文本改为“其他参与者”, 这次我们将在“其他参与者”上调用它的名称｡

140
00:12:32,600 --> 00:12:39,950
‫最后, 我将打印其他组件调用, 获取其他组件上的名称｡

141
00:12:40,130 --> 00:12:47,630
‫让我们编译一下, 回到编辑器, 我会点击播放, 发射一个炮弹, 看看这个.

142
00:12:47,660 --> 00:12:50,780
‫我们看到命中补偿是投射网格｡

143
00:12:50,780 --> 00:12:56,180
‫还记得我们说过,

144
00:12:56,180 --> 00:13:01,940
‫这是执行击打的组件, 也就是我们的投射物混搭, 你会看到它使用的是我们在创建默认子对象时给这个组件指定的名称｡

145
00:13:01,940 --> 00:13:05,570
‫这是使用该名称的情况之一｡

146
00:13:05,570 --> 00:13:09,830
‫现在你会看到它说其他演员缺陷下划线零｡

147
00:13:09,830 --> 00:13:16,130
‫这是因为这个静态网格参与者是一个名为frake underline zero的缺陷｡

148
00:13:16,130 --> 00:13:22,160
‫有时候引擎会在参与者和组件的内部名称的末尾加上一个数字, 当我们打印其他组件时,

149
00:13:22,160 --> 00:13:26,630
‫你会看到同样的事情发生了｡

150
00:13:26,630 --> 00:13:33,110
‫有缺陷的静态网格执行元有一个静态网格组件, 其名称为static mesh component zero｡

151
00:13:33,110 --> 00:13:40,610
‫这给了我们更多关于on hit回调函数中输入参数的信息｡

152
00:13:40,610 --> 00:13:48,620
‫这是很有用的, 因为我们可以访问C++中的那些对象, 如果我们想对hit事件做出响应的话｡

153
00:13:48,800 --> 00:13:57,650
‫总之, 我们已经了解了命中事件, 以及如何将这些事件实现为多播委托, 我们还了解了它们的工作原理｡

154
00:13:57,650 --> 00:14:05,030
‫我们创建了一个叫做On Hit and Bound的函数,

155
00:14:05,030 --> 00:14:09,620
‫这个函数是我们的投射网格从原始组件类继承的on组件hit委托的函数｡

156
00:14:09,620 --> 00:14:15,920
‫现在我们还没有摧毁击中的投射物, 但是我们现在知道我们可以很容易地做到这一点, 因为我们有这个回调函数,

157
00:14:15,920 --> 00:14:21,860
‫我们可以在这个函数中放置逻辑, 比如摧毁投射物｡

158
00:14:21,860 --> 00:14:24,080
‫我们将在以后的视频中介绍｡

159
00:14:24,080 --> 00:14:32,270
‫现在, 请自鸣得意, 因为这是迄今为止您所学习的Unreal Engine C++中比较复杂的领域之一｡

160
00:14:32,480 --> 00:14:33,890
‫下一个视频里见｡

