﻿1
00:00:04,260 --> 00:00:05,340
‫欢迎回来｡

2
00:00:05,700 --> 00:00:11,550
‫现在我们有了一个游戏模式, 我们想使用游戏模式来确定何时可以开始游戏｡

3
00:00:11,580 --> 00:00:17,700
‫现在, 一些游戏有一个延迟或倒计时计时器, 当游戏开始时开始｡

4
00:00:17,700 --> 00:00:23,460
‫在一段时间后, 玩家可以移动角色, 或者在我们的例子中,

5
00:00:23,460 --> 00:00:25,450
‫在世界上移动坦克｡

6
00:00:25,470 --> 00:00:28,500
‫所以我们将在这段视频中实现它｡

7
00:00:28,530 --> 00:00:35,520
‫这将涉及到首先禁用输入, 这样我们就不能在游戏开始时四处走动, 然后我们将设置一个计时器,

8
00:00:35,520 --> 00:00:41,860
‫在设定的时间后, 我们可以启用输入｡

9
00:00:41,880 --> 00:00:47,870
‫所以让我们回到调整坦克游戏模式, 并在这里添加一些东西｡

10
00:00:47,880 --> 00:00:55,380
‫首先, 我想添加一个浮点数, 表示在游戏开始后我们开始移动之前应该经过的时间｡

11
00:00:55,410 --> 00:01:06,800
‫所以这个浮点数叫做开始延迟, 我把它初始化为3点F, 这样我们在开始游戏之前要等3秒.

12
00:01:06,810 --> 00:01:12,420
‫游戏一开始, 我就想启动这个计时器, 也就是说我想用一个函数来启动这个计时器,

13
00:01:12,420 --> 00:01:16,510
‫我也要把它设为私有函数.

14
00:01:16,530 --> 00:01:21,180
‫我把它设为void函数, 叫做handle game start.

15
00:01:21,210 --> 00:01:25,200
‫现在我可以实现处理游戏开始在调坦克游戏模式｡

16
00:01:25,470 --> 00:01:28,320
‫下一步就在这里开始打｡

17
00:01:28,770 --> 00:01:36,930
‫现在我不会忘记在这里添加调坦克游戏模式类名, 现在我有了一个处理游戏启动功能｡

18
00:01:37,170 --> 00:01:40,410
‫现在, 调用此函数的地方应该是开始播放”｡

19
00:01:40,620 --> 00:01:43,590
‫因为开始Play在游戏开始时被调用｡

20
00:01:43,590 --> 00:01:47,180
‫所以我要调用手柄游戏, 从这里开始玩｡

21
00:01:47,190 --> 00:01:52,110
‫因为我们在游戏开始的时候要做一些事情, 比如设置坦克,

22
00:01:52,110 --> 00:01:58,050
‫调音坦克, 玩家, 控制器变量, 我想把这些都移到游戏开始的时候.

23
00:01:58,050 --> 00:02:03,600
‫我把它们移到handle game start, 这样tank和tune tank玩家控制器就被设置好了,

24
00:02:03,600 --> 00:02:08,940
‫因为我们在这里调用handle game start, 然后开始游戏｡

25
00:02:08,940 --> 00:02:15,990
‫因此, 我想在这里启动一个倒计时计时器, 之后我们可以启用用户输入｡

26
00:02:15,990 --> 00:02:21,480
‫现在, 在启动计时器之前, 我将禁用输入, 这样我们就不能移动坦克了｡

27
00:02:21,690 --> 00:02:24,420
‫这就需要我们的函数｡

28
00:02:24,420 --> 00:02:29,670
‫我们在这里放置了调音坦克, 播放器控制器叫设置播放器使能状态｡

29
00:02:29,670 --> 00:02:33,690
‫这意味着我将使用调音器, 播放器控制器｡

30
00:02:33,690 --> 00:02:38,400
‫如果我打算使用调音台的播放器控制器, 最好确保它是有效的｡

31
00:02:38,400 --> 00:02:46,200
‫所以我会说, 如果调整坦克, 播放器,

32
00:02:46,200 --> 00:02:57,570
‫控制器, 如果我们到达这个if语句的内部, 那么我可以调整坦克, 播放器控制器, 并调用设置播放器启用状态, 并传入false｡

33
00:02:57,690 --> 00:03:00,720
‫这样我们的坦克就无法移动了｡

34
00:03:00,720 --> 00:03:07,380
‫我看到了红色的曲线, 那是因为我说的是坦克坦克, 玩家控制器, 而不是调音坦克｡

35
00:03:07,830 --> 00:03:11,250
‫所以拼写正确了, 现在我没有错误了｡

36
00:03:11,250 --> 00:03:13,690
‫所以接下来我们需要启动一个计时器｡

37
00:03:13,710 --> 00:03:20,850
‫现在我们知道计时器涉及到使用F计时器句柄, 我们实际上可以创建一个F计时器句柄,

38
00:03:20,850 --> 00:03:25,110
‫而不是拥有一个属于该类的成员变量｡

39
00:03:25,200 --> 00:03:31,470
‫我将继续执行此操作, 并将此播放器称为启用计时器句柄｡

40
00:03:31,800 --> 00:03:38,340
‫接下来, 我们需要为回调函数设置一个计时器, 我想使用set player

41
00:03:38,340 --> 00:03:45,390
‫enabled state, 但set player enabled state是一个需要输入布尔类型的函数｡

42
00:03:45,990 --> 00:03:51,900
‫现在, 我们还没有看到如何使用需要输入参数的回调来设置计时器｡

43
00:03:51,900 --> 00:03:56,190
‫这将涉及一个新的概念, 称为计时器委托｡

44
00:03:56,190 --> 00:03:59,310
‫所以让我们来看看虚幻引擎的计时器系统｡

45
00:03:59,310 --> 00:04:07,080
‫同样, 我们知道有一个世界定时器管理器来管理我们的定时器, 它有一个设置定时器的功能｡

46
00:04:07,170 --> 00:04:11,280
‫现在, set timer函数有多个重载｡

47
00:04:11,370 --> 00:04:13,410
‫我们已经见过一个了｡

48
00:04:13,440 --> 00:04:16,710
‫现在我来谈谈这个函数的另一个版本｡

49
00:04:16,710 --> 00:04:26,760
‫这个版本需要一个计时器句柄, 一个计时器速率或者一个延迟时间, 在此期间我们必须等待回调函数被调用｡

50
00:04:26,760 --> 00:04:33,270
‫它不直接获取回调函数的地址, 而是可以获取一个称为计时器委托的东西｡

51
00:04:33,270 --> 00:04:41,490
‫这是一个F类型的结构体计时器委托, 它允许我们创建一个可以直接绑定函数的对象｡

52
00:04:41,490 --> 00:04:45,600
‫和计时器委托可以绑定需要输入参数的函数｡

53
00:04:45,600 --> 00:04:55,080
‫现在我们可以创建一个EF计时器委托变量, 并使用来自f计时器委托的create you对象函数对其进行初始化｡

54
00:04:55,110 --> 00:05:00,990
‫这将创建一个新的计时器委托, 并根据传入括号中的内容对其进行初始化｡

55
00:05:00,990 --> 00:05:03,810
‫这会采用的使用者物件｡

56
00:05:03,860 --> 00:05:08,110
‫当然, 我们的回调函数所在的类｡

57
00:05:08,120 --> 00:05:15,110
‫接下来, 它获取回调函数本身的地址, 后跟任何输入值, 一旦调用回调函数,

58
00:05:15,110 --> 00:05:18,450
‫我们就将这些值传递给回调函数｡

59
00:05:18,470 --> 00:05:25,450
‫从那里我们可以从世界计时器管理器调用set timer, 并使用接受计时器委托的重载｡

60
00:05:25,460 --> 00:05:32,300
‫这个多载需要计时器控制代码本身､ 计时器委派､

61
00:05:32,300 --> 00:05:38,630
‫播放速率或浮点数（决定呼叫回呼之前的延迟）, 然后是布林值（决定计时器是否应该循环）,

62
00:05:38,630 --> 00:05:43,310
‫让我们知道如何建立F计时器委派｡

63
00:05:43,310 --> 00:05:49,610
‫所以我希望你在新的if语句中的handle game start函数中创建一个｡

64
00:05:49,610 --> 00:05:54,200
‫因此, 创建一个本地f计时器委托并使用f计时器委托｡

65
00:05:54,200 --> 00:05:55,640
‫创建对象｡

66
00:05:55,640 --> 00:06:01,610
‫现在我们需要传入一个用户对象, 通常我们使用它作为用户对象,

67
00:06:01,610 --> 00:06:05,870
‫但是我们要调用的函数存在于播放器控制器上.

68
00:06:05,870 --> 00:06:12,320
‫因此, 传入变量tune

69
00:06:12,320 --> 00:06:20,300
‫tank播放器控制器作为第一个输入, 该输入将成为用户对象, 回调函数将设置播放器启用状态, 该函数已添加到自定义播放器控制器中｡

70
00:06:20,300 --> 00:06:25,730
‫别忘了运算符的地址, 作为第三个输入, 我们将传入值｡

71
00:06:25,730 --> 00:06:33,590
‫这是在计时器结束时调用回调时将传递到set player enabled状态的内容｡

72
00:06:33,590 --> 00:06:36,710
‫所以暂停视频, 现在就试给予这个｡

73
00:06:39,560 --> 00:06:46,580
‫在我们的计时器句柄下, 我将创建一个本地F计时器委托,

74
00:06:46,580 --> 00:06:50,540
‫我将调用这个播放器使能计时器委托.

75
00:06:51,140 --> 00:06:51,710
‫没关系, 我会的

76
00:06:51,710 --> 00:06:53,030
‫如果你给它起个别的名字｡

77
00:06:53,030 --> 00:07:00,200
‫现在我将使用f计时器初始化它, 委托, 创建您对象

78
00:07:00,470 --> 00:07:06,590
‫这将首先使用一个用户对象, 这将是我们的tune tank播放器控制器｡

79
00:07:06,590 --> 00:07:11,300
‫所以我会把tune tanks播放器控制器作为第一个输入｡

80
00:07:11,390 --> 00:07:19,250
‫对于第二个函数, 我们需要回调函数, 它是一个tune tank播放器,

81
00:07:19,910 --> 00:07:23,360
‫控制器设置播放器启用状态.

82
00:07:23,360 --> 00:07:30,290
‫我不能忘记, 我需要这个函数的运算符的地址, 我想传递给这个回调函数的值,

83
00:07:30,290 --> 00:07:34,670
‫就是这样的｡

84
00:07:34,670 --> 00:07:42,290
‫在延迟时间结束时, 当这个回调函数被调用时, true将是传递给回调函数的值｡

85
00:07:42,290 --> 00:07:48,770
‫现在我准备好调用set timer, 这意味着我需要调用get world timer管理器｡

86
00:07:48,950 --> 00:07:51,530
‫然后我可以从那里调用set timer｡

87
00:07:52,070 --> 00:08:00,560
‫我们首先要使用的函数重载有一个计时器句柄, 它是播放器使能计时器句柄.

88
00:08:00,590 --> 00:08:04,370
‫下一个要传递的输入是委托｡

89
00:08:04,370 --> 00:08:08,630
‫这就是玩家使能, 计时器委托｡

90
00:08:10,130 --> 00:08:10,520
‫下一个

91
00:08:10,520 --> 00:08:16,700
‫我们需要延迟时间, 这就是开始延迟, 也就是我们刚刚创建的浮点数｡

92
00:08:16,730 --> 00:08:20,120
‫接下来我将传递启动延迟｡

93
00:08:20,990 --> 00:08:28,430
‫最后, 我不希望这个计时器循环, 所以我将传入false, 这样我们就不会有循环行为｡

94
00:08:29,300 --> 00:08:33,020
‫现在, 我将对这些输入进行缩进处理, 使其看起来更美观｡

95
00:08:33,710 --> 00:08:38,690
‫现在我们使用新的计时器委托调用set timer｡

96
00:08:38,690 --> 00:08:45,380
‫在此延迟时间结束时, 我们应该调用回调函数set player enabled state,

97
00:08:45,380 --> 00:08:51,440
‫此时传入的值为true, 因为开始延迟为3秒, 并且在设置计时器之前, 我们调用set player

98
00:08:51,440 --> 00:08:55,190
‫enabled state时传入的值为false｡

99
00:08:55,190 --> 00:09:00,920
‫当我们按下播放键时, 我们应该在三秒延迟结束前无法移动｡

100
00:09:00,920 --> 00:09:03,590
‫让我们编译一下, 看看它是如何工作的｡

101
00:09:04,100 --> 00:09:09,140
‫所以我要继续按播放键, 我试着四处走动, 但我做不到｡

102
00:09:09,140 --> 00:09:12,470
‫3秒后我就能突然动了｡

103
00:09:12,500 --> 00:09:14,210
‫再看看这个

104
00:09:14,240 --> 00:09:17,330
‫请注意, 我的光标是十字光标｡

105
00:09:17,330 --> 00:09:23,000
‫它可能很难在屏幕上看到, 但你应该可以在屏幕上看到它就好了｡

106
00:09:23,000 --> 00:09:27,470
‫而这让我更容易瞄准和控制我的坦克｡

107
00:09:27,470 --> 00:09:28,820
‫炮塔旋转｡

108
00:09:29,210 --> 00:09:30,140
‫好极了｡

109
00:09:30,140 --> 00:09:37,370
‫总之, 我们为游戏模式创建了一个句柄game start函数, 我们调用它并开始游戏｡

110
00:09:37,580 --> 00:09:47,180
‫我们还使用一个计时器委托设置了一个计时器, 我们将播放器控制器上的set player enabled state函数绑定到了该委托上｡

111
00:09:47,180 --> 00:09:53,810
‫这允许我们为计时器提供一个函数回调, 它接受输入参数,

112
00:09:53,810 --> 00:09:58,340
‫我们使用它在游戏开始时的三秒延迟后启用用户输入｡

113
00:09:58,370 --> 00:10:03,470
‫现在, 如果玩家没有某种视觉提示, 让他们知道输入没有启用,

114
00:10:03,470 --> 00:10:05,690
‫这可能会让他们感到沮丧｡

115
00:10:05,690 --> 00:10:08,150
‫屏幕上出现了倒计时｡

116
00:10:08,150 --> 00:10:10,640
‫我们将在以后的视频中介绍这一点｡

117
00:10:10,640 --> 00:10:12,410
‫但现在, 恭喜你｡

118
00:10:12,410 --> 00:10:18,170
‫您现在知道如何将接受输入参数的函数绑定到计时器委托｡

119
00:10:18,170 --> 00:10:19,640
‫下一个视频里见｡

