﻿1
00:00:03,980 --> 00:00:05,900
‫你好, 欢迎回来｡

2
00:00:05,930 --> 00:00:10,610
‫现在我们已经创造了一个坦克, 可以移动, 甚至旋转它的炮塔｡

3
00:00:10,610 --> 00:00:18,830
‫我们现在准备创建一个塔类, 它可以继承坦克从基本pod类继承的一些功能｡

4
00:00:19,100 --> 00:00:26,000
‫现在, 一旦我们创建了一个塔类, 我们将覆盖tick函数, 这样我们就可以旋转它的炮塔了｡

5
00:00:26,030 --> 00:00:32,080
‫所以我们的目标是让炮塔旋转, 这样它们就能一直看着坦克.

6
00:00:32,090 --> 00:00:39,020
‫这样, 当他们开始发射炮弹, 他们会击中坦克有时只要坦克没有移动的方式很快｡

7
00:00:39,630 --> 00:00:43,740
‫我们还要想办法弄到坦克｡

8
00:00:43,770 --> 00:00:49,380
‫这样我们就可以瞄准坦克——然后把塔的炮塔转向坦克——｡

9
00:00:49,410 --> 00:00:52,350
‫我们准备好了一些炮弹战斗｡

10
00:00:52,650 --> 00:00:59,910
‫我现在在编辑器中, 我将进入tune tank文件夹, 基本类和tank类都在那里.

11
00:01:00,270 --> 00:01:04,650
‫现在, 我想在基类的基础上创建一个塔式类.

12
00:01:04,770 --> 00:01:07,850
‫我们在坦克课上的做法是对的｡

13
00:01:07,860 --> 00:01:14,430
‫单击base-—并选择create C++ class derived from based

14
00:01:14,430 --> 00:01:18,210
‫on（创建从基于派生的C++类）另一种方法是转到tools（工具）并选择new C++ class（新的C++类）｡

15
00:01:18,540 --> 00:01:24,630
‫在这里, 我们可以单击显示所有类的选项卡, 然后搜索base-—｡

16
00:01:24,750 --> 00:01:27,270
‫这里我们看到了我们的基类｡

17
00:01:27,480 --> 00:01:33,050
‫如果我选择此选项并单击“下一步”, 现在我将基于base-—创建一个新类｡

18
00:01:33,060 --> 00:01:38,910
‫我会把它放在和其他C++类一样的路径上, 我会把它叫做塔.

19
00:01:39,210 --> 00:01:41,070
‫因此, 让我们单击“创建类”｡

20
00:01:41,610 --> 00:01:44,720
‫这是我的新塔时代和塔点｡

21
00:01:44,790 --> 00:01:53,520
‫CP现在我们需要的第一件事是滴答功能, 因为塔要旋转它的炮塔, 面对——｡

22
00:01:53,730 --> 00:01:56,640
‫所以我们要重写tick函数｡

23
00:01:56,640 --> 00:02:03,930
‫我将创建一个新的公共部分, 我们将输入virtual void tick, 它接受一个名为Delta

24
00:02:03,930 --> 00:02:07,560
‫Time的浮点数, 这是一个覆盖值.

25
00:02:07,560 --> 00:02:14,100
‫现在, 我们将在以后的视频中详细介绍virtual和override,

26
00:02:14,100 --> 00:02:18,600
‫但我们实际上是采用继承的tick函数并为其创建新的实现｡

27
00:02:18,600 --> 00:02:23,520
‫让我们在Tower CP中实现tick函数｡

28
00:02:23,550 --> 00:02:29,370
‫现在, 我们需要在tick函数名称前面加上一个tower和双冒号｡

29
00:02:29,370 --> 00:02:34,950
‫和往常一样, 跟注超级分笔成交点是一个好主意, 我们需要传递Delta时间｡

30
00:02:34,950 --> 00:02:42,390
‫现在我想做的是旋转坦克炮塔, 使炮塔威胁到坦克, 并准备发射炮弹｡

31
00:02:42,390 --> 00:02:45,870
‫但我想只有在坦克在射程内时才能这么做｡

32
00:02:46,170 --> 00:02:53,750
‫现在, 为了知道坦克是否在射程内, 我们需要知道从炮塔到坦克的距离｡

33
00:02:53,760 --> 00:02:57,510
‫这里有一个小发明代表了世界的起源

34
00:02:57,510 --> 00:03:01,470
‫换句话说, 就是空间中X､ Y和Z为零的点｡

35
00:03:01,470 --> 00:03:08,970
‫现在, 当我们谈论一个演员的位置时, 我们谈论的是从原点到那个位置的向量｡

36
00:03:08,970 --> 00:03:17,430
‫我们总是可以通过获取演员位置来获取位置向量, 这样我们就可以得到其中一个塔的位置和坦克的位置｡

37
00:03:17,430 --> 00:03:21,930
‫如果我们知道这两个位置, 我们就可以计算出它们之间的距离｡

38
00:03:21,930 --> 00:03:28,470
‫现在, 我们可以用向量数学来做这个, 但是F向量类有一个函数, 叫做dist,

39
00:03:28,470 --> 00:03:33,810
‫这个函数取位置向量, 它返回的是它们之间的距离｡

40
00:03:33,810 --> 00:03:41,940
‫在塔CP文件中, 在tick函数中, 我将写几个注释, 以便我们知道应该做什么｡

41
00:03:41,940 --> 00:03:52,890
‫首先, 我们需要找到距离坦克后, 检查, 看看坦克是否在范围内,

42
00:03:52,890 --> 00:03:58,170
‫如果在范围内旋转炮塔对坦克｡

43
00:03:59,070 --> 00:04:00,960
‫所以我们有一些事情要做｡

44
00:04:01,140 --> 00:04:05,820
‫现在, 为了找到到坦克的距离, 我们需要抓住坦克｡

45
00:04:05,850 --> 00:04:08,640
‫现在, 一个很好的地方是这样做的开始发挥｡

46
00:04:08,640 --> 00:04:13,350
‫因此, 除了tick函数之外, 让我们继续并覆盖开始Play｡

47
00:04:13,380 --> 00:04:17,580
‫现在注意在坦克H, 开始发挥是在一个保护区｡

48
00:04:17,580 --> 00:04:21,210
‫我们也要把它保护在塔里｡

49
00:04:21,210 --> 00:04:28,380
‫因此, 我们将把protected部分放在public部分下面, 并在tick下面实现开始play｡

50
00:04:28,380 --> 00:04:35,580
‫让我们转到Tower Dot, CP, implement, 开始play, 完全限定函数名, 正如您可能猜到的,

51
00:04:35,580 --> 00:04:38,670
‫我们调用Super Begin Play｡

52
00:04:38,790 --> 00:04:44,310
‫现在, 为了获取tank并将其存储在变量中, 我们需要一个类型为tank的变量｡

53
00:04:44,310 --> 00:04:49,200
‫所以我们要把它放在H塔的一个私人区域｡

54
00:04:49,200 --> 00:04:55,290
‫这是一个A型坦克, 它是一个指针, 我们可以简单地称它为坦克｡

55
00:04:55,290 --> 00:05:03,000
‫为了避免在这里包括坦克H, 我们可以提前声明, 我们已经看到了它的重要性｡

56
00:05:03,360 --> 00:05:09,540
‫现在我们有了这个坦克指针, 如果我们知道如何进入坦克, 我们就可以把它存储在坦克指针里,

57
00:05:09,540 --> 00:05:11,970
‫然后开始游戏.

58
00:05:12,000 --> 00:05:18,510
‫我首先要做的是把坦克H包括进去, 这样我们就可以使用这个类型了｡

59
00:05:18,510 --> 00:05:20,580
‫那我们怎么进入水箱？

60
00:05:20,580 --> 00:05:26,220
‫好吧, 这里有一个名为get player pawn的实用函数的虚幻引擎文档｡

61
00:05:26,310 --> 00:05:29,100
‫它存在于一个游戏静态｡

62
00:05:29,160 --> 00:05:35,910
‫既然我已经打开了它, 我将继续复制游戏静态的include, 并查看语法｡

63
00:05:35,910 --> 00:05:39,060
‫它有两个输入一个世界上下文对象｡

64
00:05:39,470 --> 00:05:42,950
‫我们已经知道如何处理这一点和球员指数｡

65
00:05:42,950 --> 00:05:53,660
‫就像我们在单人博弈中看到的, 参与者索引总是0号参与者这样我们就可以访问0号参与者对应的棋子.

66
00:05:54,050 --> 00:05:57,650
‫我们把这个函数叫做塔点CP｡

67
00:05:57,680 --> 00:06:04,850
‫我将粘贴include, 然后在开始播放时,

68
00:06:04,850 --> 00:06:12,290
‫我将把tank设置为等于你的游戏静态, get player-—对于世界上下文对象｡

69
00:06:12,290 --> 00:06:17,910
‫我可以传递这个, 对于球员指数, 我们可以传递零｡

70
00:06:17,930 --> 00:06:19,970
‫现在看看红色的曲线｡

71
00:06:19,970 --> 00:06:26,120
‫它说A型兵的值不能赋给A型坦克的实体｡

72
00:06:26,150 --> 00:06:35,810
‫这与我们在尝试调用､ 获取控制器并将结果存储在A播放器控制器中时遇到的问题完全相同｡

73
00:06:35,870 --> 00:06:42,200
‫坦克是兵的子级, 所以我们不能在子指针中存储父类型｡

74
00:06:42,200 --> 00:06:43,370
‫我们必须这样做｡

75
00:06:44,150 --> 00:06:46,060
‫你猜对了, 我们得赶了｡

76
00:06:46,070 --> 00:06:51,830
‫所以我们要把返回的值放在一个转换函数调用中.

77
00:06:51,830 --> 00:06:56,000
‫所以我们要说cast我们要对坦克施法｡

78
00:06:56,000 --> 00:07:02,300
‫我们要传递给投出的是这个让玩家Pond跟注的指令｡

79
00:07:02,300 --> 00:07:04,850
‫所以我们把它放在括号里｡

80
00:07:04,850 --> 00:07:09,260
‫施法完毕后我们就能进入水箱了｡

81
00:07:09,380 --> 00:07:16,310
‫现在我们已经接触到了水箱, 我们可以找到水箱的距离, 距离就是浮子的距离.

82
00:07:16,310 --> 00:07:20,240
‫所以我们可以做一个局部浮点变量叫做distance｡

83
00:07:20,600 --> 00:07:27,380
‫我们要设置它等于调用F向量静态函数dist的结果｡

84
00:07:27,410 --> 00:07:31,700
‫现在, dist接受两个类型为F vector的输入参数｡

85
00:07:31,880 --> 00:07:34,850
‫现在我们需要空间中两点之间的距离｡

86
00:07:34,850 --> 00:07:37,010
‫一是塔位｡

87
00:07:37,010 --> 00:07:43,190
‫我们在塔类中, 所以我们可以调用获取演员位置, 这样就得到了塔的位置｡

88
00:07:43,190 --> 00:07:44,660
‫但是坦克呢？

89
00:07:44,660 --> 00:07:50,870
‫好吧, 我们可以打电话给坦克, 得到演员的位置, 现在我们有了距离｡

90
00:07:50,870 --> 00:07:57,110
‫现在唯一的问题是, 我们在使用tank指针时没有首先检查它是否为空｡

91
00:07:57,290 --> 00:08:06,860
‫所以我们必须先说if tank然后我们可以把这个函数调用拖到if语句里.

92
00:08:06,860 --> 00:08:13,190
‫因此, 如果tank是有效的, 那么我们可以通过get actor location访问它的位置｡

93
00:08:13,190 --> 00:08:14,030
‫好极了｡

94
00:08:14,030 --> 00:08:19,130
‫因为我们在处理if语句,

95
00:08:19,130 --> 00:08:24,410
‫我将把其他的注释移到里面, 因为我们知道我们不能检查坦克是否在范围内, 如果坦克是无效的｡

96
00:08:24,590 --> 00:08:28,790
‫所以我想挑战你把炮塔转向坦克｡

97
00:08:28,790 --> 00:08:33,020
‫现在, 我们只想在坦克在射程内的情况下这样做, 我们有距离｡

98
00:08:33,020 --> 00:08:35,240
‫所以现在我们需要一个射程变量｡

99
00:08:35,240 --> 00:08:40,490
‫因此, 在塔类中创建一个名为fire range的浮动对象, 并使用属性将其公开｡

100
00:08:40,490 --> 00:08:42,980
‫我们希望能够在编辑器中编辑此内容｡

101
00:08:43,010 --> 00:08:45,890
‫现在你要检查一下坦克是否在射程内｡

102
00:08:45,890 --> 00:08:50,630
‫如果叫旋转炮塔, 旋转炮塔需要一个看目标的角度｡

103
00:08:50,630 --> 00:08:53,180
‫你要通过坦克的位置｡

104
00:08:53,180 --> 00:08:56,660
‫暂停视频, 立即执行此行为｡

105
00:09:00,030 --> 00:09:00,420
‫好吧, 我会的

106
00:09:00,420 --> 00:09:02,370
‫所以我们需要一个射程变量｡

107
00:09:02,370 --> 00:09:05,940
‫所以在H座, 我们有一个私人区域｡

108
00:09:05,940 --> 00:09:07,680
‫我们要做一个花车｡

109
00:09:08,340 --> 00:09:16,650
‫我把这个叫做射程, 我会把它初始化为, 比如说, 300华氏度.

110
00:09:16,650 --> 00:09:21,030
‫但我们会尝试一下, 因为这将是一个你的财产｡

111
00:09:21,240 --> 00:09:22,860
‫所以你的财产｡

112
00:09:22,860 --> 00:09:29,910
‫因为我想让所有坦克都有相同的射程, 所以我会把它设为默认值.

113
00:09:29,910 --> 00:09:33,270
‫因此, 我们只能在默认蓝本上编辑它｡

114
00:09:33,300 --> 00:09:38,940
‫现在, 如果您在任何地方进行编辑, 或者只编辑实例, 这完全没有问题｡

115
00:09:38,940 --> 00:09:42,090
‫这是一个偏好的问题, 我们可以稍后更改｡

116
00:09:42,090 --> 00:09:46,710
‫我也会给予它一个类别, 我会把这个类别叫做战斗｡

117
00:09:46,740 --> 00:09:50,820
‫让我们进入CP塔, 这里有下一个点｡

118
00:09:50,820 --> 00:09:59,160
‫检查坦克是否在射程内, 这意味着我们需要检查距离是否小于或等于射程｡

119
00:09:59,160 --> 00:10:04,860
‫我们有小于或等于而不仅仅是等于,

120
00:10:04,860 --> 00:10:11,970
‫因为从一帧到另一帧, 距离实际上可能大于一帧的射击范围, 而小于射击范围的下一帧完全掠过射击范围｡

121
00:10:11,970 --> 00:10:15,870
‫所以它实际上可能永远不会完全等于射程｡

122
00:10:15,870 --> 00:10:20,820
‫实际上, 对于浮点值, 两个浮点值完全相等是非常罕见的｡

123
00:10:20,820 --> 00:10:27,630
‫所以我们有这个如果检查, 如果我们到达它的内部, 这意味着距离小于或等于射程｡

124
00:10:27,630 --> 00:10:33,120
‫坦克现在在射程内, 这意味着这条评论可以移动到那里｡

125
00:10:33,960 --> 00:10:42,180
‫现在, 如果在射程内, 将炮塔转向坦克, 这意味着我们要调用旋转炮塔功能.

126
00:10:42,390 --> 00:10:45,690
‫这是我们放在基地舱里的保护功能｡

127
00:10:45,720 --> 00:10:51,060
‫现在转动炮塔看看目标, 我们需要坦克的位置｡

128
00:10:51,060 --> 00:10:55,410
‫所以这将是坦克得到演员的位置｡

129
00:10:55,410 --> 00:11:02,010
‫我们现在称之为旋转炮塔只有当坦克在射程内｡

130
00:11:02,010 --> 00:11:05,040
‫让我们编译一下, 看看它是如何工作的｡

131
00:11:05,340 --> 00:11:12,030
‫我们回到了编辑器, 我们需要做的是进入蓝图, 兵, 找到一个BP兵炮塔,

132
00:11:12,030 --> 00:11:15,120
‫打开完整的蓝图编辑器｡

133
00:11:15,120 --> 00:11:22,170
‫现在在右上方, 我们看到了父职业的基础兵, 但是我们希望我们的父职业是塔, 这样我们就可以进入职业设置,

134
00:11:22,170 --> 00:11:27,930
‫父职业, 搜索塔并选择它｡

135
00:11:27,960 --> 00:11:31,980
‫现在我们的兵炮塔是基于塔类的｡

136
00:11:31,980 --> 00:11:34,710
‫现在让我们看看当我们点击播放时会发生什么｡

137
00:11:35,070 --> 00:11:37,200
‫好吧, 我在移动水箱｡

138
00:11:37,200 --> 00:11:40,560
‫我们不在射程内, 所以我们没有看到任何来自塔的移动｡

139
00:11:40,560 --> 00:11:44,100
‫但如果我进入射程, 看看这个｡

140
00:11:44,100 --> 00:11:47,970
‫现在他们跟着我, 看起来很危险｡

141
00:11:48,120 --> 00:11:52,080
‫现在300个单位并不遥远｡

142
00:11:52,080 --> 00:11:55,440
‫所以我想做的就是编辑这个距离｡

143
00:11:55,440 --> 00:12:00,840
‫因此, 从这里在BP典当炮塔, 我将选择BP池塘炮塔自己｡

144
00:12:00,840 --> 00:12:02,850
‫这是战斗部分｡

145
00:12:02,850 --> 00:12:06,840
‫我将把它设置为大约700｡

146
00:12:07,890 --> 00:12:13,350
‫现在, 如果我点击播放, 我会看到当我回到这里时, 它们不会旋转｡

147
00:12:13,350 --> 00:12:16,410
‫但我一进入射程, 他们就盯上我了｡

148
00:12:18,180 --> 00:12:19,020
‫好极了｡

149
00:12:20,030 --> 00:12:23,120
‫总之, 我们创建了塔式机类｡

150
00:12:23,120 --> 00:12:25,720
‫我们现在有一个敌人的坦克｡

151
00:12:25,730 --> 00:12:33,770
‫我们还在滴答功能中旋转塔的炮塔朝向坦克, 我们只在坦克在射程内时才这样做｡

152
00:12:33,770 --> 00:12:39,650
‫我们还公开了射程变量, 以便可以在蓝图中调整｡

153
00:12:39,770 --> 00:12:41,600
‫我们几乎准备好战斗了｡

154
00:12:41,630 --> 00:12:44,450
‫我们将在接下来的视频中开始设置｡

155
00:12:44,630 --> 00:12:45,620
‫我很快就会见到你的｡

