﻿1
00:00:04,710 --> 00:00:06,600
‫你好, 欢迎回来｡

2
00:00:06,630 --> 00:00:09,660
‫现在, 我们准备开始处理用户输入｡

3
00:00:09,780 --> 00:00:16,650
‫这意味着我们要按键盘键, 移动鼠标, 点击鼠标, 看看我们的坦克对输入的反应｡

4
00:00:16,770 --> 00:00:22,260
‫现在, 为了做到这一点, 我们首先需要实际获得输入,

5
00:00:22,260 --> 00:00:24,450
‫我们首先要开始使用轴映射来做这件事｡

6
00:00:24,450 --> 00:00:25,980
‫我们来谈谈这个吧｡

7
00:00:26,100 --> 00:00:30,600
‫现在, 在项目中, 让我们转到编辑和项目设置｡

8
00:00:30,780 --> 00:00:35,340
‫如果我们向下滚动并选择input, 则会在此处看到绑定｡

9
00:00:35,340 --> 00:00:39,600
‫在绑定下有动作映射和轴映射｡

10
00:00:39,630 --> 00:00:42,300
‫我们首先要学习轴映射｡

11
00:00:42,350 --> 00:00:49,700
‫现在, 您可能对这些产品有一些经验, 但我们将更深入地了解它们的功能和工作原理｡

12
00:00:49,710 --> 00:00:51,150
‫所以我们有三个｡

13
00:00:51,240 --> 00:01:00,780
‫如果我单击下拉箭头, 我会在这里看到W和SW, 这是键盘上的W和SW键｡

14
00:01:00,810 --> 00:01:06,960
‫这些将指定给此特定轴映射, 称为“向前移动”｡

15
00:01:06,960 --> 00:01:09,870
‫我们来讨论一下轴映射的工作原理｡

16
00:01:09,870 --> 00:01:20,820
‫我们在虚幻编辑器中看到, 我们有一个称为“向前移动”的轴映射, 它将W和SCS分配给了这个轴映射｡

17
00:01:20,820 --> 00:01:22,950
‫那么这到底意味着什么呢？

18
00:01:23,730 --> 00:01:27,870
‫在Unreal Engine中, 我们有一个叫做轴映射的东西｡

19
00:01:27,870 --> 00:01:32,970
‫而轴映射是处理游戏中每一帧的东西｡

20
00:01:33,000 --> 00:01:35,700
‫可以为轴映射指定关键点｡

21
00:01:35,700 --> 00:01:38,460
‫在本例中, 我们指定了W和S｡

22
00:01:38,490 --> 00:01:41,370
‫现在看一下W键旁边｡

23
00:01:41,370 --> 00:01:45,060
‫在我右边的小截图示例中, 它显示了比例｡

24
00:01:45,060 --> 00:01:48,180
‫在刻度旁边是数字1｡  0.

25
00:01:48,300 --> 00:01:53,160
‫你们可能已经注意到, 在SQ旁边的刻度是-1｡  0.

26
00:01:53,160 --> 00:01:58,650
‫这些值将影响输入信息｡

27
00:01:58,650 --> 00:02:01,080
‫以下是轴映射的工作原理｡

28
00:02:01,320 --> 00:02:08,580
‫我们的轴映射前移有能力与C++中的一个函数相关联｡

29
00:02:08,700 --> 00:02:15,060
‫现在, 当涉及到轴映射时,

30
00:02:15,060 --> 00:02:22,410
‫如果我们将函数与轴映射相关联, 则它需要接受浮点类型的输入参数, 以便我们可以在池塘上创建一个名为MOVE的函数, 该函数接受浮点｡

31
00:02:22,410 --> 00:02:24,870
‫我们只调用这个输入参数值｡

32
00:02:24,930 --> 00:02:30,570
‫现在有一种方法可以把这个函数和我们的向前移动轴映射联系起来｡

33
00:02:30,570 --> 00:02:34,980
‫它表示我们将移动函数绑定到轴映射｡

34
00:02:34,980 --> 00:02:43,680
‫所以游戏的每一帧虚幻引擎的输入系统都要检查我们是按W键还是键｡

35
00:02:43,680 --> 00:02:51,600
‫它会根据我们是否按下这些键和每一帧来计算轴的值｡

36
00:02:51,600 --> 00:02:58,080
‫它会调用这个函数, 我们已经绑定了这个函数来向前移动, 并传递轴的值｡

37
00:02:58,080 --> 00:03:03,810
‫函数内部发生的任何事情都取决于我们作为C++开发人员｡

38
00:03:03,840 --> 00:03:05,310
‫下面是它的工作原理｡

39
00:03:05,310 --> 00:03:10,860
‫如果我们没有按W或键, 这个轴的值为零｡

40
00:03:10,860 --> 00:03:19,620
‫因此绑定到向前移动轴映射的move函数在每一帧都被调用, 传入的浮点值为零｡

41
00:03:19,620 --> 00:03:22,380
‫现在, 假设我们按下W键｡

42
00:03:22,620 --> 00:03:26,820
‫W键的比例设定为1｡  0.

43
00:03:26,850 --> 00:03:33,870
‫这意味着我们的坐标轴值将为1｡  0, 这就是传递给MOV函数的内容｡

44
00:03:33,870 --> 00:03:39,090
‫因此, 每一帧, move函数的调用值为1｡  0已传入｡

45
00:03:39,120 --> 00:03:44,910
‫现在, 假设我们按下SRC, 其比例值为-1｡  0.

46
00:03:44,940 --> 00:03:51,720
‫这意味着每一帧move函数都将被调用, 并且-1｡  将传入0｡

47
00:03:51,720 --> 00:03:58,260
‫现在我们同时按下W和S键, 这两个值会加在一起｡

48
00:03:58,260 --> 00:04:05,040
‫所以我们得到1｡  按W键得到0, 得到-1｡  按下SRC时为0｡

49
00:04:05,070 --> 00:04:07,200
‫现在这两个互相抵消了｡

50
00:04:07,320 --> 00:04:13,350
‫所以如果我们同时按下两个键, 调用move函数时会传入0｡

51
00:04:13,710 --> 00:04:19,020
‫所以根据我们按下的按键组合,

52
00:04:19,020 --> 00:04:25,230
‫我们会得到一个不同的值传递给MOVE函数, 我们可以对这个值做任何我们喜欢的事情, 比如用它来移动棋子｡

53
00:04:25,230 --> 00:04:28,500
‫我们很快就会讨论如何移动棋子｡

54
00:04:28,500 --> 00:04:36,390
‫现在, 让我们先进行实际设置, 以便能够处理来自Axis映射系统的信息｡

55
00:04:36,930 --> 00:04:43,260
‫好了, 现在我们知道了Axis映射的工作原理, 接下来是时候创建一个回调函数了, 我们可以将它绑定到move

56
00:04:43,260 --> 00:04:46,620
‫forward轴映射｡

57
00:04:46,620 --> 00:04:50,370
‫因此, 我将关闭项目设置, 并跳回到VS代码｡

58
00:04:50,370 --> 00:04:58,470
‫在这里的VS代码中, 我们想要创建一个函数, 它可以绑定到move forward轴映射｡

59
00:04:58,470 --> 00:05:02,640
‫所以在池H中, 我们可以创建一个私有函数｡

60
00:05:02,640 --> 00:05:03,810
‫现在它就要有了｡

61
00:05:03,880 --> 00:05:07,180
‫void返回类型, 我想调用这个move｡

62
00:05:07,210 --> 00:05:11,950
‫现在它需要一个浮点输入参数, 我们将调用这个值.

63
00:05:12,010 --> 00:05:16,750
‫让我们在Tank中定义移动函数.

64
00:05:16,970 --> 00:05:27,310
‫我会把它放在构造函数下面, 我们需要一个函数名前面有作用域解析操作符的tank｡

65
00:05:27,460 --> 00:05:33,550
‫所以我们有了这个移动函数, 我们准备把它绑定到向前移动轴映射上｡

66
00:05:33,670 --> 00:05:39,340
‫这是在一个名为setup player input component的函数中完成的｡

67
00:05:39,370 --> 00:05:40,630
‫这听起来应该很熟悉｡

68
00:05:40,630 --> 00:05:48,130
‫事实上, 如果我们打开浏览器并返回Base蓬特H, 我们可以向下滚动并在public部分看到function setup

69
00:05:48,130 --> 00:05:51,910
‫player input组件｡

70
00:05:51,910 --> 00:05:56,380
‫我们将看到这是一个继承的虚函数的重写｡

71
00:05:56,950 --> 00:06:06,010
‫现在, 基本spawn类实际上不需要设置任何输入, 这就是这个函数处理来自播放器的输入的目的｡

72
00:06:06,040 --> 00:06:10,810
‫现在, 我们的bond基类不需要处理输入, 但我们的tank类需要｡

73
00:06:10,810 --> 00:06:19,240
‫所以我们可以把这个函数从基池h中取出来, 但我要复制它, 因为tank中需要它｡

74
00:06:19,930 --> 00:06:27,190
‫复制这个函数, 我将把它粘贴到H罐的公共部分｡

75
00:06:27,190 --> 00:06:32,800
‫因为我们不需要它在基础池, 我只是要删除它从基础池类｡

76
00:06:32,800 --> 00:06:38,090
‫事实上, 我将进入基础池CP, 并将其从这里移除｡

77
00:06:38,110 --> 00:06:42,250
‫因此, 让我们继续从Base Pond中删除设置玩家输入组件｡

78
00:06:42,460 --> 00:06:46,540
‫现在它不再属于基本池塘类｡

79
00:06:46,540 --> 00:06:52,120
‫因此, 让我们继续并保存更改, 然后关闭基础池塘H和CP｡

80
00:06:52,150 --> 00:06:59,410
‫现在, 我们已经在Tank H中声明了setup播放器输入组件, 但我们还想定义它和tank｡

81
00:06:59,620 --> 00:07:01,540
‫所以在坦克指挥部

82
00:07:01,720 --> 00:07:06,340
‫我将在move函数的上面添加一个定义｡

83
00:07:06,430 --> 00:07:12,880
‫所以这是一个空的, 它是一个坦克设置玩家输入组件｡

84
00:07:13,510 --> 00:07:18,000
‫现在, 让我们回到坦克H, 看看它的输入参数类型是什么｡

85
00:07:18,010 --> 00:07:21,880
‫你会看到它在括号里是正向声明的｡

86
00:07:21,880 --> 00:07:27,070
‫如果你想在头文件中声明一个类类型, 你可以这样做｡

87
00:07:27,070 --> 00:07:34,990
‫所以这里是正向声明的, 我们需要这个输入组件指针类型, 这个参数叫做播放器输入组件.

88
00:07:34,990 --> 00:07:37,450
‫因此, 我们需要在tank中输入这个参数｡

89
00:07:37,600 --> 00:07:44,980
‫在括号中的设置播放器输入组件, 我们将有一个U输入组件, 它是一个指针,

90
00:07:45,040 --> 00:07:50,080
‫它被称为播放器输入组件｡

91
00:07:50,320 --> 00:07:55,300
‫所以现在函数签名与函数声明中的签名匹配｡

92
00:07:55,450 --> 00:08:02,050
‫现在回到CP文件, 我们给予这个函数一个函数体, 我们要覆盖这个函数,

93
00:08:02,050 --> 00:08:07,450
‫调用超级设置播放器输入组件是个好主意｡

94
00:08:07,480 --> 00:08:13,030
‫现在, 由于我们要调用setupplayer输入组件的父版本, 因此必须传入一个类型为you

95
00:08:13,030 --> 00:08:15,460
‫input组件的输入｡

96
00:08:15,460 --> 00:08:19,900
‫我们要把输入参数传递给这个函数.

97
00:08:19,900 --> 00:08:23,430
‫所以这样父类将调用它的版本｡

98
00:08:23,440 --> 00:08:26,620
‫现在基塘的水箱还没有实现这个功能｡

99
00:08:26,620 --> 00:08:27,700
‫我们刚把它移走了｡

100
00:08:27,700 --> 00:08:31,930
‫但是基类的父类——将调用它的版本｡

101
00:08:31,930 --> 00:08:38,410
‫无论何时重写这样的虚函数, 调用超级版本都是一个好主意｡

102
00:08:38,410 --> 00:08:43,090
‫因此, 我们不会错过父版本中实现的任何功能｡

103
00:08:43,090 --> 00:08:44,440
‫那我们为什么要这么做？

104
00:08:44,470 --> 00:08:47,150
‫设置播放器输入组件的好处是什么？

105
00:08:47,170 --> 00:08:51,730
‫它的优点之一是绑定函数来访问映射｡

106
00:08:51,730 --> 00:08:56,140
‫我们希望将移动函数绑定到向前移动轴映射｡

107
00:08:56,140 --> 00:08:57,250
‫而我们在这里就是这么做的｡

108
00:08:57,250 --> 00:09:01,180
‫我们使用这个输入参数播放器输入组件来完成此操作｡

109
00:09:01,180 --> 00:09:04,360
‫这就是这个物体的设计目的｡

110
00:09:04,390 --> 00:09:14,110
‫我们使用播放器输入组件, 并在此指针上使用箭头操作符访问一个名为bind axis的函数｡

111
00:09:14,590 --> 00:09:17,890
‫现在“绑定轴”需要一些输入参数｡

112
00:09:17,890 --> 00:09:22,450
‫第一个是字符串文字, 这意味着我们将使用文本宏｡

113
00:09:22,600 --> 00:09:24,430
‫现在我们在引号里写什么呢？

114
00:09:24,520 --> 00:09:27,160
‫我们把轴的名称映射出来｡

115
00:09:27,160 --> 00:09:31,690
‫我们在编辑器中看到, 这个轴映射称为向前移动｡

116
00:09:32,020 --> 00:09:36,970
‫因此, 我们选择该轴映射绑定到第二个输入参数｡

117
00:09:36,970 --> 00:09:43,690
‫这将是一个指向对象的指针,

118
00:09:43,690 --> 00:09:53,280
‫而绑定函数的对象是一个指向特定类的实例的指针, 因为我们在坦克类中, 这将指向游戏中坦克兵的实例.

119
00:09:53,290 --> 00:09:58,120
‫现在第三个参数是我们要绑定的函数的地址｡

120
00:09:58,120 --> 00:10:01,720
‫所以我们有一个坦克移动｡

121
00:10:01,750 --> 00:10:03,550
‫非常重要的是, 我们需要充分｡

122
00:10:03,660 --> 00:10:06,900
‫用类名限定函数名｡

123
00:10:06,900 --> 00:10:13,200
‫在函数名的前面, 我们需要运算符的地址｡

124
00:10:13,230 --> 00:10:19,220
‫现在, 如果你不熟悉这样做, 这只是取一个函数的地址｡

125
00:10:19,230 --> 00:10:23,040
‫函数可以像变量一样有地址｡

126
00:10:23,040 --> 00:10:28,320
‫因此使用运算符的地址是一种将函数传递到其他函数的方法｡

127
00:10:28,320 --> 00:10:31,380
‫所以我们需要接线员的地址｡

128
00:10:31,380 --> 00:10:34,050
‫因此, 我们有函数调用来绑定访问｡

129
00:10:34,200 --> 00:10:41,700
‫现在, 您可能注意到IntelliSense错误指针指向不完整的类类型, 您输入的组件是不允许的｡

130
00:10:41,850 --> 00:10:43,710
‫现在我们知道是什么导致了这个｡

131
00:10:43,710 --> 00:10:46,950
‫首先, 这可能意味着我们需要包含一个头文件｡

132
00:10:47,220 --> 00:10:50,430
‫另一种可能性是, 这是一个虚假的错误｡

133
00:10:50,430 --> 00:10:55,110
‫你可以通过编译很容易地找到答案, 所以让我们试着编译一下｡

134
00:10:55,440 --> 00:10:57,600
‫我们将看到编译成功｡

135
00:10:57,600 --> 00:10:59,640
‫所以我们知道这是一个虚假的错误｡

136
00:10:59,640 --> 00:11:04,290
‫但同样, 如果需要, 您可以添加include来删除它｡

137
00:11:04,290 --> 00:11:05,790
‫所以你不介意｡

138
00:11:05,820 --> 00:11:10,890
‫现在我们知道它所抱怨的类类型是输入组件｡

139
00:11:11,280 --> 00:11:16,290
‫这是文档中的输入组件, 这是包含组件｡

140
00:11:16,290 --> 00:11:23,100
‫如果我们把这个加到坦克CP文件的顶部, 我们就可以去掉那个讨厌的假错误｡

141
00:11:23,100 --> 00:11:29,280
‫同样, 因为这些pragya想要包含guard, 我们知道输入组件不会被包含超过一次,

142
00:11:29,280 --> 00:11:34,080
‫所以它们消失了｡

143
00:11:34,350 --> 00:11:39,900
‫现在我们知道, 每一帧都会调用这个move函数, value会有一个特定的浮点值,

144
00:11:39,900 --> 00:11:44,280
‫这取决于我们是按W还是问｡

145
00:11:44,670 --> 00:11:50,490
‫现在, 仅仅知道move函数一定会向前移动是不够的｡

146
00:11:50,490 --> 00:11:54,750
‫作为开发人员, 能够确认一切正常是件好事｡

147
00:11:54,750 --> 00:12:01,110
‫所以我希望你们在挑战中使用MOV函数中的YUI log,

148
00:12:01,110 --> 00:12:04,950
‫打印传递给move的float调用值.

149
00:12:04,980 --> 00:12:13,110
‫所以在uiy log中使用percent f, 把浮点数的值记录到输出日志中, 然后测试一下这个游戏,

150
00:12:13,110 --> 00:12:17,020
‫按下这些键, 看看你会打印出什么｡

151
00:12:17,040 --> 00:12:20,370
‫暂停视频, 现在将其添加到移动功能中｡

152
00:12:23,280 --> 00:12:23,590
‫好吧, 我会的

153
00:12:23,610 --> 00:12:27,960
‫所以在mov函数中, 我将添加一个uii日志｡

154
00:12:30,200 --> 00:12:33,680
‫这可能是日志临时警告｡

155
00:12:33,770 --> 00:12:35,960
‫而对于文本宏｡

156
00:12:36,230 --> 00:12:42,440
‫我只需要把值, %, F和值｡

157
00:12:42,710 --> 00:12:43,520
‫现在没事了｡

158
00:12:43,520 --> 00:12:48,500
‫如果您使用了不同的详细程度或警告类型, 如果您知道如何执行这些操作｡

159
00:12:48,950 --> 00:12:49,960
‫没关系的

160
00:12:49,970 --> 00:12:58,100
‫我在这里只使用一个警告, 我知道您已经使用了percent se之类的东西, 并使用字符串值格式化了日志｡

161
00:12:58,130 --> 00:13:04,300
‫Percent F（如果您不知道的话）是使用浮点值格式化UI日志的方法｡

162
00:13:04,310 --> 00:13:12,380
‫让我们编译它, 然后回到编辑器中, 我将打开输出日志并按“播放”, 然后检查它,

163
00:13:12,380 --> 00:13:16,190
‫在那里用无数的消息向输出日志发送垃圾邮件｡

164
00:13:16,190 --> 00:13:19,000
‫现在, 我将在视口中单击并按W键｡

165
00:13:19,010 --> 00:13:22,030
‫这是我的值1, 我要释放它.

166
00:13:22,040 --> 00:13:23,180
‫一切都归零了｡

167
00:13:23,210 --> 00:13:26,570
‫我按下这个键, 结果是负1

168
00:13:26,570 --> 00:13:30,500
‫如果我们同时按两个键, 我们得到零｡

169
00:13:30,500 --> 00:13:33,620
‫这和我们预期的完全一样

170
00:13:33,800 --> 00:13:34,650
‫好极了｡

171
00:13:34,670 --> 00:13:35,390
‫好吧, 我会的

172
00:13:35,390 --> 00:13:39,320
‫在本视频中, 我们设置了池塘来处理一些用户输入｡

173
00:13:39,560 --> 00:13:46,180
‫我们讨论了访问映射, 并将move函数绑定到前移访问映射.

174
00:13:46,190 --> 00:13:53,300
‫然后, 我们在MOVE函数中使用YUI日志打印该访问值, 但实际上我们希望移动坦克,

175
00:13:53,300 --> 00:13:57,130
‫而不是仅将一些值打印到输出日志｡

176
00:13:57,140 --> 00:14:02,720
‫在接下来的课上, 我们会把它设置好, 这样我们就可以开始移动水箱了.

177
00:14:03,290 --> 00:14:04,310
‫我很快就会见到你的｡

