‫Welcome back.
‫Now we have a game mode and we'd like to use the game mode to determine when we can start the game.
‫Now, some games have a delay or a countdown timer that starts when the game starts.
‫And after a set amount of time, then the player is allowed to move the character or in our case, the
‫tank around in the world.
‫So we're going to implement that in this video.
‫This is going to involve first disabling the input so we can't move around when the game first starts
‫and then we're going to set a timer and after a set amount of time, then we can enable input.
‫So let's go back to tune tanks game mode and add a couple of things here.
‫First, I'd like to add a float for the amount of time that should pass when the game starts before
‫we can start moving.
‫So this float is going to be called start delay and I'm going to initialize this to three point F so
‫that we have to wait 3 seconds before we can start the game.
‫Now, as soon as the game starts, I'd like to start this timer, which means I'd like a function that
‫will start this timer, and I'm going to make this a private function as well.
‫I'm going to make this a void function called handle game start.
‫Now I can implement handle game start in tune tanks game mode.
‫Step down here under begin play.
‫Now I won't forget to add the tune tanks game mode class name here and now I have a handle game start
‫function.
‫Now the place to call this would be Begin Play.
‫Since Begin Play is called at the start of the game.
‫So I'm going to call handle game, start here and begin play.
‫And since we're doing a couple of things here at the beginning of the game where setting the tank and
‫the tune tanks, player, controller variables, I'd like to move these into handle game start.
‫So I'm going to move those right down into handle game start and that way tank and tune tanks player
‫controller will be set since we're calling handle game start here and begin play.
‫So here is where I would like to start a countdown timer after which we can enable user input.
‫Now before we start the timer, I'm going to disable input so we can't move the tank just yet.
‫And that's going to require our function.
‫We placed here in tune tanks, player controller called set player enabled state.
‫And that means I'm going to use tune tanks, player controller.
‫And if I'm going to use tune tank's player controller, it's a good idea to make sure it's valid.
‫So I'm going to say if tune tanks, player, controller and if we reach the inside of this if statement,
‫then I can take tune tanks, player controller and call set player enabled state and pass in false.
‫And that way our tank will not be able to move.
‫And I see the red squiggles and that's because I said tank tanks, player controller rather than tune
‫tanks.
‫So spelling it correctly now I get no errors there.
‫So next we need to start a timer.
‫Now we know that timers involve using an F timer handle and we can actually create an F timer handle
‫rather than having a member variable that belongs to the class.
‫So I'm going to go ahead and do that and I'm going to call this player enable timer handle.
‫And next, we need to set a timer now for the callback function for our timer, I'd like to use set
‫player enabled state, but set player enabled state is a function that requires an input of type boolean.
‫Now we haven't seen how to set a timer using a callback that requires input parameters.
‫This is going to involve a new concept called a timer delegate.
‫So let's take a look at Unreal Engine's timer system.
‫Again, we know that there's a world timer manager which manages our timers and it has a set timer function.
‫Now there are multiple overloads of the set timer function.
‫We've seen one of them already.
‫Now I'm going to talk about another version of this function.
‫And this version requires a timer handle, a timer rate or a delay time during which we must wait before
‫our callback function gets called.
‫And instead of taking the address of a callback function directly, it can take something called a timer
‫delegate.
‫This is a struct of type F timer delegate, which allows us to create an object that can bind a function
‫directly to it.
‫And timer delegates can bind functions that require input parameters.
‫Now we can create an EF timer delegate variable and initialize it using the create you object function
‫from f timer delegate.
‫This will create a new timer delegate and initialize it based on what we pass into the parentheses.
‫This will take a user object which is of.
‫Of course, the class that our callback function exists on.
‫And next it takes the address of the callback function itself, followed by any input values that we
‫would like passed into our callback once it gets called.
‫From there we can call set timer from the world timer manager and use the overload that takes a timer
‫delegate.
‫This overload requires the timer handle itself, the timer delegate, the play rate or a float that
‫determines the delay before which our callback will be called, and then a boolean to determine whether
‫or not our timer should loop so we know how to create an F timer delegate.
‫So I'd like you to create one in the handle game start function inside of our new if statement.
‫So create a local f timer delegate and use f timer delegate.
‫Create you object.
‫Now we're going to need to pass in a user object and usually we've been using this as the user object,
‫but the function we'd like called exists on the player controller.
‫So pass in are variable tune tanks player controller as the first input that's going to be the user
‫object and the callback function is going to be set player enabled state that function we added to our
‫custom player controller.
‫Don't forget the address of operator and as the third input we're going to pass in the value.
‫True, this is what will be passed into set player enabled state when our callback gets called at the
‫end of the timer.
‫So pause the video and give this a try now.
‫So just under our timer handle, I'm going to create a local F timer delegate and I'm going to call
‫this player enable timer delegate.
‫That's okay.
‫If you named it something else.
‫Now I'm going to initialize this using f timer, delegate, create you object.
‫And this will first take a user object and that's going to be our tune tanks player controller.
‫So I'm going to say tune tanks player controller as the first input.
‫And for the second we need our callback function and that's going to be a tune tanks player, controller
‫set player enabled state.
‫And I can't forget, I need the address of operator for this function address and the value that I'd
‫like passed into this callback function is going to be true that way.
‫At the end of the delay time, when this callback gets called true will be the value passed in to the
‫callback function.
‫Now I'm ready to call set timer, which means I need to call get world timer manager.
‫And then from there I can call set timer.
‫And the function overload we're using first takes a timer handle and that's going to be player enable
‫timer handle.
‫The next input I'm going to pass in will be the delegate.
‫So that's going to be player enable, timer delegate.
‫Next.
‫We need our delay time and that's going to be start delay, which is the float we just created.
‫So next I'm passing in start delay.
‫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
‫behavior.
‫Now I'm going to go ahead and indent these inputs so it looks pretty.
‫And now we're calling set timer using our new timer delegate.
‫And at the end of this delay time we should get our callback function set player enabled state called
‫with the value true passed in now since start delay is 3 seconds and we're calling set player enabled
‫state passing in false before we set our timer.
‫When we press play, we shouldn't be able to move until this three second delay is up.
‫So let's compile this and see how it works.
‫So I'm going to go ahead and hit play and I'm trying to move around and I can't.
‫And after 3 seconds I can suddenly move.
‫And also check this out.
‫Notice that my cursor is the crosshairs.
‫It may be hard to see on the screen, but you should be able to see it on your screen just fine.
‫And this makes it a lot easier for me to aim and control my tanks.
‫Turret rotation.
‫Perfect.
‫So in summary, we created a handle game start function for the game mode and we're calling this and
‫begin play.
‫And we also set a timer using a timer delegate onto which we bound our set player enabled state function
‫on the player controller.
‫This allowed us to have a function callback for our timer that takes input parameters and we use this
‫to enable user input after a three second delay when the game starts.
‫Now, this could be frustrating for a player if they didn't have some sort of visual cue, sort of letting
‫them know that input is not enabled.
‫Something like a countdown on the screen.
‫So we'll take care of that in future videos.
‫But for now, congratulations.
‫You now know how to bind a function that takes input parameters to a timer delegate.
‫I'll see you in the next video.