﻿1
00:00:04,260 --> 00:00:05,340
‫Welcome back.

2
00:00:05,700 --> 00:00:11,550
‫Now we have a game mode and we'd like to use the game mode to determine when we can start the game.

3
00:00:11,580 --> 00:00:17,700
‫Now, some games have a delay or a countdown timer that starts when the game starts.

4
00:00:17,700 --> 00:00:23,460
‫And after a set amount of time, then the player is allowed to move the character or in our case, the

5
00:00:23,460 --> 00:00:25,450
‫tank around in the world.

6
00:00:25,470 --> 00:00:28,500
‫So we're going to implement that in this video.

7
00:00:28,530 --> 00:00:35,520
‫This is going to involve first disabling the input so we can't move around when the game first starts

8
00:00:35,520 --> 00:00:41,860
‫and then we're going to set a timer and after a set amount of time, then we can enable input.

9
00:00:41,880 --> 00:00:47,870
‫So let's go back to tune tanks game mode and add a couple of things here.

10
00:00:47,880 --> 00:00:54,030
‫First, I'd like to add a float for the amount of time that should pass when the game starts before

11
00:00:54,030 --> 00:00:55,380
‫we can start moving.

12
00:00:55,410 --> 00:01:03,120
‫So this float is going to be called start delay and I'm going to initialize this to three point F so

13
00:01:03,120 --> 00:01:06,800
‫that we have to wait 3 seconds before we can start the game.

14
00:01:06,810 --> 00:01:12,420
‫Now, as soon as the game starts, I'd like to start this timer, which means I'd like a function that

15
00:01:12,420 --> 00:01:16,510
‫will start this timer, and I'm going to make this a private function as well.

16
00:01:16,530 --> 00:01:21,180
‫I'm going to make this a void function called handle game start.

17
00:01:21,210 --> 00:01:25,200
‫Now I can implement handle game start in tune tanks game mode.

18
00:01:25,470 --> 00:01:28,320
‫Step down here under begin play.

19
00:01:28,770 --> 00:01:36,090
‫Now I won't forget to add the tune tanks game mode class name here and now I have a handle game start

20
00:01:36,090 --> 00:01:36,930
‫function.

21
00:01:37,170 --> 00:01:40,410
‫Now the place to call this would be Begin Play.

22
00:01:40,620 --> 00:01:43,590
‫Since Begin Play is called at the start of the game.

23
00:01:43,590 --> 00:01:47,180
‫So I'm going to call handle game, start here and begin play.

24
00:01:47,190 --> 00:01:52,110
‫And since we're doing a couple of things here at the beginning of the game where setting the tank and

25
00:01:52,110 --> 00:01:58,050
‫the tune tanks, player, controller variables, I'd like to move these into handle game start.

26
00:01:58,050 --> 00:02:03,600
‫So I'm going to move those right down into handle game start and that way tank and tune tanks player

27
00:02:03,600 --> 00:02:08,940
‫controller will be set since we're calling handle game start here and begin play.

28
00:02:08,940 --> 00:02:15,990
‫So here is where I would like to start a countdown timer after which we can enable user input.

29
00:02:15,990 --> 00:02:21,480
‫Now before we start the timer, I'm going to disable input so we can't move the tank just yet.

30
00:02:21,690 --> 00:02:24,420
‫And that's going to require our function.

31
00:02:24,420 --> 00:02:29,670
‫We placed here in tune tanks, player controller called set player enabled state.

32
00:02:29,670 --> 00:02:33,690
‫And that means I'm going to use tune tanks, player controller.

33
00:02:33,690 --> 00:02:38,400
‫And if I'm going to use tune tank's player controller, it's a good idea to make sure it's valid.

34
00:02:38,400 --> 00:02:46,200
‫So I'm going to say if tune tanks, player, controller and if we reach the inside of this if statement,

35
00:02:46,200 --> 00:02:57,570
‫then I can take tune tanks, player controller and call set player enabled state and pass in false.

36
00:02:57,690 --> 00:03:00,720
‫And that way our tank will not be able to move.

37
00:03:00,720 --> 00:03:06,780
‫And I see the red squiggles and that's because I said tank tanks, player controller rather than tune

38
00:03:06,780 --> 00:03:07,380
‫tanks.

39
00:03:07,830 --> 00:03:11,250
‫So spelling it correctly now I get no errors there.

40
00:03:11,250 --> 00:03:13,690
‫So next we need to start a timer.

41
00:03:13,710 --> 00:03:20,850
‫Now we know that timers involve using an F timer handle and we can actually create an F timer handle

42
00:03:20,850 --> 00:03:25,110
‫rather than having a member variable that belongs to the class.

43
00:03:25,200 --> 00:03:31,470
‫So I'm going to go ahead and do that and I'm going to call this player enable timer handle.

44
00:03:31,800 --> 00:03:38,340
‫And next, we need to set a timer now for the callback function for our timer, I'd like to use set

45
00:03:38,340 --> 00:03:45,390
‫player enabled state, but set player enabled state is a function that requires an input of type boolean.

46
00:03:45,990 --> 00:03:51,900
‫Now we haven't seen how to set a timer using a callback that requires input parameters.

47
00:03:51,900 --> 00:03:56,190
‫This is going to involve a new concept called a timer delegate.

48
00:03:56,190 --> 00:03:59,310
‫So let's take a look at Unreal Engine's timer system.

49
00:03:59,310 --> 00:04:07,080
‫Again, we know that there's a world timer manager which manages our timers and it has a set timer function.

50
00:04:07,170 --> 00:04:11,280
‫Now there are multiple overloads of the set timer function.

51
00:04:11,370 --> 00:04:13,410
‫We've seen one of them already.

52
00:04:13,440 --> 00:04:16,710
‫Now I'm going to talk about another version of this function.

53
00:04:16,710 --> 00:04:24,570
‫And this version requires a timer handle, a timer rate or a delay time during which we must wait before

54
00:04:24,570 --> 00:04:26,760
‫our callback function gets called.

55
00:04:26,760 --> 00:04:32,550
‫And instead of taking the address of a callback function directly, it can take something called a timer

56
00:04:32,550 --> 00:04:33,270
‫delegate.

57
00:04:33,270 --> 00:04:40,440
‫This is a struct of type F timer delegate, which allows us to create an object that can bind a function

58
00:04:40,440 --> 00:04:41,490
‫directly to it.

59
00:04:41,490 --> 00:04:45,600
‫And timer delegates can bind functions that require input parameters.

60
00:04:45,600 --> 00:04:53,370
‫Now we can create an EF timer delegate variable and initialize it using the create you object function

61
00:04:53,370 --> 00:04:55,080
‫from f timer delegate.

62
00:04:55,110 --> 00:05:00,990
‫This will create a new timer delegate and initialize it based on what we pass into the parentheses.

63
00:05:00,990 --> 00:05:03,810
‫This will take a user object which is of.

64
00:05:03,860 --> 00:05:08,110
‫Of course, the class that our callback function exists on.

65
00:05:08,120 --> 00:05:15,110
‫And next it takes the address of the callback function itself, followed by any input values that we

66
00:05:15,110 --> 00:05:18,450
‫would like passed into our callback once it gets called.

67
00:05:18,470 --> 00:05:24,830
‫From there we can call set timer from the world timer manager and use the overload that takes a timer

68
00:05:24,830 --> 00:05:25,450
‫delegate.

69
00:05:25,460 --> 00:05:32,300
‫This overload requires the timer handle itself, the timer delegate, the play rate or a float that

70
00:05:32,300 --> 00:05:38,630
‫determines the delay before which our callback will be called, and then a boolean to determine whether

71
00:05:38,630 --> 00:05:43,310
‫or not our timer should loop so we know how to create an F timer delegate.

72
00:05:43,310 --> 00:05:49,610
‫So I'd like you to create one in the handle game start function inside of our new if statement.

73
00:05:49,610 --> 00:05:54,200
‫So create a local f timer delegate and use f timer delegate.

74
00:05:54,200 --> 00:05:55,640
‫Create you object.

75
00:05:55,640 --> 00:06:01,610
‫Now we're going to need to pass in a user object and usually we've been using this as the user object,

76
00:06:01,610 --> 00:06:05,870
‫but the function we'd like called exists on the player controller.

77
00:06:05,870 --> 00:06:12,320
‫So pass in are variable tune tanks player controller as the first input that's going to be the user

78
00:06:12,320 --> 00:06:18,890
‫object and the callback function is going to be set player enabled state that function we added to our

79
00:06:18,890 --> 00:06:20,300
‫custom player controller.

80
00:06:20,300 --> 00:06:25,730
‫Don't forget the address of operator and as the third input we're going to pass in the value.

81
00:06:25,730 --> 00:06:32,330
‫True, this is what will be passed into set player enabled state when our callback gets called at the

82
00:06:32,330 --> 00:06:33,590
‫end of the timer.

83
00:06:33,590 --> 00:06:36,710
‫So pause the video and give this a try now.

84
00:06:39,560 --> 00:06:46,580
‫So just under our timer handle, I'm going to create a local F timer delegate and I'm going to call

85
00:06:46,580 --> 00:06:50,540
‫this player enable timer delegate.

86
00:06:51,140 --> 00:06:51,710
‫That's okay.

87
00:06:51,710 --> 00:06:53,030
‫If you named it something else.

88
00:06:53,030 --> 00:07:00,200
‫Now I'm going to initialize this using f timer, delegate, create you object.

89
00:07:00,470 --> 00:07:06,590
‫And this will first take a user object and that's going to be our tune tanks player controller.

90
00:07:06,590 --> 00:07:11,300
‫So I'm going to say tune tanks player controller as the first input.

91
00:07:11,390 --> 00:07:19,250
‫And for the second we need our callback function and that's going to be a tune tanks player, controller

92
00:07:19,910 --> 00:07:23,360
‫set player enabled state.

93
00:07:23,360 --> 00:07:30,290
‫And I can't forget, I need the address of operator for this function address and the value that I'd

94
00:07:30,290 --> 00:07:34,670
‫like passed into this callback function is going to be true that way.

95
00:07:34,670 --> 00:07:41,120
‫At the end of the delay time, when this callback gets called true will be the value passed in to the

96
00:07:41,120 --> 00:07:42,290
‫callback function.

97
00:07:42,290 --> 00:07:48,770
‫Now I'm ready to call set timer, which means I need to call get world timer manager.

98
00:07:48,950 --> 00:07:51,530
‫And then from there I can call set timer.

99
00:07:52,070 --> 00:07:59,030
‫And the function overload we're using first takes a timer handle and that's going to be player enable

100
00:07:59,060 --> 00:08:00,560
‫timer handle.

101
00:08:00,590 --> 00:08:04,370
‫The next input I'm going to pass in will be the delegate.

102
00:08:04,370 --> 00:08:08,630
‫So that's going to be player enable, timer delegate.

103
00:08:10,130 --> 00:08:10,520
‫Next.

104
00:08:10,520 --> 00:08:16,700
‫We need our delay time and that's going to be start delay, which is the float we just created.

105
00:08:16,730 --> 00:08:20,120
‫So next I'm passing in start delay.

106
00:08:20,990 --> 00:08:27,590
‫And finally, I don't want this timer to loop, so I'm going to pass in false so that we don't get looping

107
00:08:27,590 --> 00:08:28,430
‫behavior.

108
00:08:29,300 --> 00:08:33,020
‫Now I'm going to go ahead and indent these inputs so it looks pretty.

109
00:08:33,710 --> 00:08:38,690
‫And now we're calling set timer using our new timer delegate.

110
00:08:38,690 --> 00:08:45,380
‫And at the end of this delay time we should get our callback function set player enabled state called

111
00:08:45,380 --> 00:08:51,440
‫with the value true passed in now since start delay is 3 seconds and we're calling set player enabled

112
00:08:51,440 --> 00:08:55,190
‫state passing in false before we set our timer.

113
00:08:55,190 --> 00:09:00,920
‫When we press play, we shouldn't be able to move until this three second delay is up.

114
00:09:00,920 --> 00:09:03,590
‫So let's compile this and see how it works.

115
00:09:04,100 --> 00:09:09,140
‫So I'm going to go ahead and hit play and I'm trying to move around and I can't.

116
00:09:09,140 --> 00:09:12,470
‫And after 3 seconds I can suddenly move.

117
00:09:12,500 --> 00:09:14,210
‫And also check this out.

118
00:09:14,240 --> 00:09:17,330
‫Notice that my cursor is the crosshairs.

119
00:09:17,330 --> 00:09:23,000
‫It may be hard to see on the screen, but you should be able to see it on your screen just fine.

120
00:09:23,000 --> 00:09:27,470
‫And this makes it a lot easier for me to aim and control my tanks.

121
00:09:27,470 --> 00:09:28,820
‫Turret rotation.

122
00:09:29,210 --> 00:09:30,140
‫Perfect.

123
00:09:30,140 --> 00:09:36,440
‫So in summary, we created a handle game start function for the game mode and we're calling this and

124
00:09:36,440 --> 00:09:37,370
‫begin play.

125
00:09:37,580 --> 00:09:45,830
‫And we also set a timer using a timer delegate onto which we bound our set player enabled state function

126
00:09:45,830 --> 00:09:47,180
‫on the player controller.

127
00:09:47,180 --> 00:09:53,810
‫This allowed us to have a function callback for our timer that takes input parameters and we use this

128
00:09:53,810 --> 00:09:58,340
‫to enable user input after a three second delay when the game starts.

129
00:09:58,370 --> 00:10:03,470
‫Now, this could be frustrating for a player if they didn't have some sort of visual cue, sort of letting

130
00:10:03,470 --> 00:10:05,690
‫them know that input is not enabled.

131
00:10:05,690 --> 00:10:08,150
‫Something like a countdown on the screen.

132
00:10:08,150 --> 00:10:10,640
‫So we'll take care of that in future videos.

133
00:10:10,640 --> 00:10:12,410
‫But for now, congratulations.

134
00:10:12,410 --> 00:10:18,170
‫You now know how to bind a function that takes input parameters to a timer delegate.

135
00:10:18,170 --> 00:10:19,640
‫I'll see you in the next video.

