﻿1
00:00:04,550 --> 00:00:11,000
‫在这节课中,

2
00:00:11,000 --> 00:00:21,050
‫我们将组装一个玩家控制器, 它将从游戏模式中接收游戏结束的信息, 并将创建这种重新启动行为, 在玩家死亡后5秒重新加载级别｡

3
00:00:21,050 --> 00:00:22,730
‫让我们来看看它是如何完成的｡

4
00:00:23,360 --> 00:00:30,710
‫所以当游戏结束时, 我们需要通知玩家控制器, 我们也需要在C++中有一个玩家控制器,

5
00:00:30,710 --> 00:00:38,000
‫这样我们就可以实现允许我们重新启动关卡的行为｡

6
00:00:38,210 --> 00:00:44,360
‫所以首先要做的是当这个点被删除时, 首先, 我们只是不加选择地进行日志记录｡

7
00:00:44,360 --> 00:00:48,200
‫我们确实想检查一下游戏是否结束了｡

8
00:00:48,200 --> 00:00:50,390
‫现在, 有两种情况｡

9
00:00:50,390 --> 00:00:52,730
‫一个是我们赢的地方, 一个是我们输的地方｡

10
00:00:52,760 --> 00:00:55,580
‫输球是我要处理的第一个问题, 因为这是最容易的｡

11
00:00:55,580 --> 00:00:58,220
‫如果被杀的兵是你失去的玩家, 那就是它｡

12
00:00:58,220 --> 00:01:04,850
‫你可能会选择在这个游戏模式的不同迭代中拥有多个生命, 但我不会这样做｡

13
00:01:04,850 --> 00:01:06,170
‫我只想过单身生活｡

14
00:01:06,170 --> 00:01:07,520
‫如果你死了, 游戏结束｡

15
00:01:07,520 --> 00:01:08,900
‫您可能需要重新启动｡

16
00:01:09,320 --> 00:01:13,640
‫那么我们如何检查这个兵是否是玩家控制器呢？

17
00:01:13,670 --> 00:01:14,990
‫好吧, 这很简单｡

18
00:01:14,990 --> 00:01:22,700
‫我们只需要对玩家控制器和被杀的兵进行强制转换｡

19
00:01:22,700 --> 00:01:25,340
‫然后如果这个不为空｡

20
00:01:25,340 --> 00:01:34,490
‫让我们取一个指针, 一个播放器控制器指针, 把它叫做播放器控制器, 把指针的结果存储在这里｡

21
00:01:34,490 --> 00:01:42,890
‫我们基本上可以说, 如果这个指针不为空, 那么如果玩家的控制器不是空指针, 那么我们就知道是玩家死了,

22
00:01:43,190 --> 00:01:47,540
‫游戏结束了.

23
00:01:47,630 --> 00:01:52,100
‫所以我们要做的就是调用播放器控制器方法｡

24
00:01:52,100 --> 00:01:57,500
‫我们已经暗示了这样一个事实, 即有一种游戏已经结束的方法｡

25
00:01:57,500 --> 00:01:58,460
‫让我们来看看这个｡

26
00:01:58,460 --> 00:02:06,530
‫如果我们做一个控制P, 看看玩家控制器,

27
00:02:06,530 --> 00:02:14,780
‫我们要寻找一个游戏结束了, 你可以看到这里有一个虚方法, 叫做游戏结束了, 你可以看到有一个结束游戏的焦点｡

28
00:02:14,780 --> 00:02:19,970
‫在游戏的最后我们应该关注哪个角色, 这是一个空指针, 这可能就是我们要用到的.

29
00:02:20,690 --> 00:02:22,910
‫然后我们会说, 这是赢家吗？

30
00:02:22,910 --> 00:02:28,340
‫基本上, 你必须让球员控制, 并知道他们是否赢了｡

31
00:02:28,340 --> 00:02:31,760
‫在这种情况下, 这是相当简单的｡

32
00:02:31,760 --> 00:02:33,050
‫不, 他们没有｡

33
00:02:33,140 --> 00:02:41,480
‫所以我们要做一个游戏控制器箭头游戏结束了, 然后我会把指针置为空, 因为我们并不需要这个功能,

34
00:02:41,480 --> 00:02:47,540
‫然后就是赢家.

35
00:02:47,540 --> 00:02:49,430
‫它只会是假的｡

36
00:02:49,430 --> 00:02:53,540
‫这不是获胜的游戏控制器, 因为它是刚刚死亡的那个｡

37
00:02:54,370 --> 00:02:56,950
‫所以现在是时候让你来实现一点挑战了｡

38
00:02:56,950 --> 00:02:59,710
‫游戏已在游戏控制器中结束｡

39
00:02:59,860 --> 00:03:06,940
‫这意味着我们需要创建一个C++玩家控制器, 创建它的蓝图子类, 默认情况下从我们的游戏模式中生成蓝图子类,

40
00:03:06,940 --> 00:03:12,530
‫然后你想继续覆盖｡

41
00:03:12,550 --> 00:03:17,350
‫游戏已经结束了, 并在那里放了一个日志消息, 以检查我们是否确实得到了｡

42
00:03:17,350 --> 00:03:19,830
‫这场游戏结束得正是时候｡

43
00:03:19,840 --> 00:03:21,220
‫暂停视频, 开始体验｡

44
00:03:21,250 --> 00:03:21,580
‫好吧, 我会的

45
00:03:21,580 --> 00:03:22,260
‫欢迎回来｡

46
00:03:22,270 --> 00:03:30,760
‫第一步, 创建C++播放器控制器, 创建一个新的C++类, 然后查找播放器控制器｡

47
00:03:30,760 --> 00:03:34,720
‫接下来, 我们将把它称为射击游戏控制器｡

48
00:03:34,750 --> 00:03:36,010
‫继续创建该类｡

49
00:03:36,010 --> 00:03:44,560
‫完成后, 我们要转到蓝图并创建一个基于蓝图的蓝图类｡

50
00:03:44,560 --> 00:03:53,200
‫所以我们想把射击游戏控制器作为基础选择, 我们把它叫做哔哔声下划线射击游戏控制器.

51
00:03:53,200 --> 00:03:59,230
‫目前并不需要这样做, 但在以后, 我们会希望将一些UI资源连接到这个播放器控制器｡

52
00:03:59,230 --> 00:04:00,940
‫所以我们会准备好的｡

53
00:04:01,150 --> 00:04:07,900
‫然后我们将进入哔声, 更多的游戏模式, 并停靠在那里,

54
00:04:07,900 --> 00:04:13,150
‫因为我们要将默认的播放器控制器类从播放器控制器更改为我们的哔声下划线射击播放器控制器｡

55
00:04:13,450 --> 00:04:14,050
‫好的, 谢谢

56
00:04:14,380 --> 00:04:18,280
‫然后我们要推翻我们的游戏已经结束｡

57
00:04:18,490 --> 00:04:21,430
‫现在我们来看一下播放器控制器｡

58
00:04:22,060 --> 00:04:24,550
‫我们可以看到, 这是在公共部分｡

59
00:04:24,550 --> 00:04:25,360
‫这是签名｡

60
00:04:25,360 --> 00:04:25,990
‫我们来复制它｡

61
00:04:25,990 --> 00:04:31,390
‫进入我们的射击游戏控制器H, 创建公共｡

62
00:04:32,170 --> 00:04:35,650
‫到那个虚拟的虚空游戏已经结束｡

63
00:04:35,650 --> 00:04:36,190
‫好的, 谢谢

64
00:04:36,190 --> 00:04:40,210
‫我们已经有了一个覆盖, 因为它显然是从某个地方被覆盖到的｡

65
00:04:41,160 --> 00:04:45,330
‫然后我们可以做的是继续实施它｡

66
00:04:45,340 --> 00:04:48,780
‫控制移位p我们要调用超级记住｡

67
00:04:49,790 --> 00:04:53,060
‫而我们要做的游戏也就这样结束了｡

68
00:04:53,870 --> 00:05:01,770
‫我们想把最后一局的重点放在B上, B是赢家, 然后我们想记录｡

69
00:05:01,790 --> 00:05:02,810
‫所以你记录｡

70
00:05:02,900 --> 00:05:04,280
‫用我的宏｡

71
00:05:04,610 --> 00:05:07,240
‫我们已经完了｡

72
00:05:07,250 --> 00:05:10,310
‫最后将显示日志消息｡

73
00:05:10,310 --> 00:05:12,880
‫让我们编译一下, 看看它是否有效｡

74
00:05:12,890 --> 00:05:14,540
‫我们将转到输出日志｡

75
00:05:14,690 --> 00:05:17,690
‫按播放键, 去送死吧｡

76
00:05:17,690 --> 00:05:23,480
‫基本健康的情况正在缓慢下降, 然后我们应该会看到一条消息｡

77
00:05:23,480 --> 00:05:24,530
‫我们明白了吗？

78
00:05:24,530 --> 00:05:24,920
‫不, 不, 不

79
00:05:24,920 --> 00:05:25,880
‫让我们来看看｡

80
00:05:25,880 --> 00:05:27,230
‫这里的播放器控制器是什么？

81
00:05:27,230 --> 00:05:32,870
‫哔声下划线射手球员控制器似乎是正确的｡

82
00:05:32,870 --> 00:05:35,570
‫我们的超驰游戏结束了｡

83
00:05:35,570 --> 00:05:37,250
‫现在我发现了一个错误｡

84
00:05:37,250 --> 00:05:42,170
‫你们中的一些人可能已经注意到了,

85
00:05:42,170 --> 00:05:49,760
‫并且一直在屏幕上大喊, 我们在这里有我们的玩家控制器, 我们正在铸造, 我得到了与玩家的实际混淆—-.

86
00:05:49,760 --> 00:05:57,260
‫所以我们要做的是, 我们要说的是, 得到被杀的控制器｡

87
00:05:57,260 --> 00:06:05,030
‫所以, killed, dot, get, controller, Aron, 箭头, get, controller,

88
00:06:05,030 --> 00:06:08,600
‫然后我们要把它转换成播放器控制器, 如果它是空的, 好的, 应该可以.

89
00:06:08,600 --> 00:06:10,760
‫让我们来试试看｡

90
00:06:10,820 --> 00:06:12,320
‫继续按播放键｡

91
00:06:12,800 --> 00:06:14,030
‫再去送死｡

92
00:06:15,700 --> 00:06:18,940
‫而且这次我们也收不到任何日志消息｡

93
00:06:18,940 --> 00:06:21,370
‫这一次有个微妙的原因｡

94
00:06:21,490 --> 00:06:24,550
‫那是因为我们正在脱离控制器｡

95
00:06:24,640 --> 00:06:26,890
‫在我们称之为——杀｡

96
00:06:26,890 --> 00:06:32,740
‫所以当它试图获得控制权的时候——实际上是空的, 不再有控制权了｡

97
00:06:32,740 --> 00:06:38,470
‫因此, 我们需要在从控制器分离之前执行此通知｡

98
00:06:38,620 --> 00:06:42,220
‫这包括向上移动, 以获得我们的游戏模式｡

99
00:06:42,220 --> 00:06:43,600
‫我以为那不重要｡

100
00:06:43,660 --> 00:06:47,200
‫但现在我仔细想想, 是的, 当然是这样｡

101
00:06:47,200 --> 00:06:50,170
‫所以让我们回到我们的水平来玩吧｡

102
00:06:50,500 --> 00:06:51,970
‫我们去挨枪子儿吧｡

103
00:06:51,970 --> 00:06:56,940
‫一旦完成, 你可以看到我们已经完成了得到打印, 因为我们想要的｡

104
00:06:56,950 --> 00:06:59,020
‫所以我们沿着遇到了一些小问题｡

105
00:06:59,020 --> 00:07:01,660
‫如果你在挑战赛中没有得到这一点, 那不是你的错｡

106
00:07:01,660 --> 00:07:03,730
‫你已经做了所有的事情｡

107
00:07:03,730 --> 00:07:04,990
‫这是伟大的｡

108
00:07:04,990 --> 00:07:11,050
‫所以希望你能试着调试一下, 但是不要担心你会被这些东西卡住｡

109
00:07:11,350 --> 00:07:17,890
‫我想做的最后一件事是在计时器上重新启动游戏｡

110
00:07:17,980 --> 00:07:25,960
‫现在, 我们可以这样做是相当简单的, 因为播放器控制器实际上有一个重启方法｡

111
00:07:25,960 --> 00:07:30,220
‫因此, 如果我们看一下这个, 它应该是一个重启级别｡

112
00:07:30,220 --> 00:07:35,590
‫这就是我们要调用的, 我们要在计时器上执行此操作｡

113
00:07:35,590 --> 00:07:44,050
‫我们以前用过定时器来重复一些事情, 但我们也可以用它来延迟一个动作一定的时间｡

114
00:07:44,050 --> 00:07:50,170
‫我将转到射击游戏玩家控制器H, 在这里创建一个私有属性.

115
00:07:50,890 --> 00:07:56,740
‫私人可以是你的属性, 这是编辑任何地方｡

116
00:07:58,620 --> 00:07:59,160
‫浮起来｡

117
00:07:59,160 --> 00:08:02,940
‫这将是重新启动延迟｡

118
00:08:03,060 --> 00:08:05,760
‫你可以看到为什么我们需要一个蓝图基地, 这已经｡

119
00:08:05,790 --> 00:08:08,400
‫我将给予它5/2延迟｡

120
00:08:08,610 --> 00:08:16,920
‫然后我将进入C++, 我们要做一个get timer世界定时器管理器｡

121
00:08:17,520 --> 00:08:19,850
‫然后我们就可以在那上面做｡

122
00:08:19,860 --> 00:08:21,870
‫那我们就得加入｡

123
00:08:21,870 --> 00:08:27,120
‫所以哈希包含, 它就是计时器管理器.

124
00:08:27,390 --> 00:08:33,210
‫然后我们应该可以使用DOT操作符, 因为这里的返回类型是一个引用, 我们要设置一个计时器,

125
00:08:33,210 --> 00:08:38,160
‫在这里我们需要传入一个计时器句柄｡

126
00:08:38,160 --> 00:08:40,590
‫在私有分区中, 让我们创建一个｡

127
00:08:40,590 --> 00:08:46,470
‫它是一个F计时器句柄, 我把它叫做重启计时器｡

128
00:08:46,470 --> 00:08:51,230
‫这就是我们传递给集合计时器的句柄｡

129
00:08:51,240 --> 00:08:59,130
‫第五个签名需要的下一件事就是我们要调用的对象, 就是这个.

130
00:08:59,460 --> 00:09:05,280
‫然后, 我认为应该是方法本身｡

131
00:09:05,490 --> 00:09:08,280
‫所以我们可以用&来表示｡

132
00:09:08,280 --> 00:09:16,200
‫实际上是方法, restart级别的方法, 我们要调用的是在A播放器控制器上定义的方法.

133
00:09:16,200 --> 00:09:17,910
‫所以一个玩家控制器｡

134
00:09:19,300 --> 00:09:19,660
‫卡伦｡

135
00:09:19,660 --> 00:09:28,210
‫Cullen重新启动级别, 然后我们只需要传入我们已经定义为重新启动延迟的延迟｡

136
00:09:28,630 --> 00:09:36,800
‫所以这样做, 把一个分号在那里结束, 希望我们应该得到自己重新启动后, 5秒｡

137
00:09:36,820 --> 00:09:42,520
‫现在让测试变得简单一点打开我们的步枪让它更具杀伤力.

138
00:09:42,520 --> 00:09:48,160
‫所以我会选择默认值, 造成50的伤害, 所以我们两枪就能被干掉.

139
00:09:48,280 --> 00:09:49,900
‫我们去玩吧｡

140
00:09:50,750 --> 00:09:52,250
‫快点把自己给杀了｡

141
00:09:53,260 --> 00:10:00,460
‫5秒后, 希望我们能重新开始, 我们重新开始, 我们又回到了那个关卡.

142
00:10:00,460 --> 00:10:03,130
‫所以计时器按我们的预期工作｡

143
00:10:03,640 --> 00:10:11,410
‫在以后的版本中, 您会发现不是重新启动, 而是会看到一条错误消息, 看起来像这样, 它讲述了传输失败,

144
00:10:11,410 --> 00:10:18,550
‫并讲述了UUID､ PID､ 沙箱等内容｡

145
00:10:18,580 --> 00:10:23,650
‫当我们试图重启并检查重启是否正常时, 我们必须绕过这个问题,

146
00:10:23,650 --> 00:10:31,920
‫我们进入点, 点, 点菜单, 而不是播放菜单, 我们必须作为一个独立的游戏来玩｡

147
00:10:31,930 --> 00:10:38,110
‫如果, 如果你玩作为一个独立的游戏, 它需要一点时间来启动,

148
00:10:38,110 --> 00:10:41,620
‫但重新启动将像预期的那样工作｡

149
00:10:41,620 --> 00:10:43,600
‫我们可以看到关卡已经重新加载｡

150
00:10:43,600 --> 00:10:46,570
‫现在, 显然没有太多的迹象表明这会发生｡

151
00:10:46,570 --> 00:10:50,170
‫所以我们会在下一节课中讨论UI｡

152
00:10:50,170 --> 00:10:51,010
‫我会看到你在那里｡

