Okay, well, we've got our main PowerUp logic in place. So now, the next thing to do, I think, is incorporate some logic to decide what the conditions are for engaging the PowerUpMeter, you know, decrement from it and so on. And then, actually decide what the PowerUp gives us, what kind of game mechanic it introduces. So, let's start in the PowerUpManager by creating a field to store our PowerUp state. So, either on or off ... On, off. What type do you think would best store this information? That's right, a bool. So, let's do that right now. Let's say, "Public bool is powered." We're going to need it to be public, I think, so other classes can access it. And, we'll start off ... When the script starts, we'll just set that to ... Well, it already defaults by default to false in C#. bools default to false. Uh, so, but let's set it explicitly in the start, so we know what it's supposed to start off as. And then here, what we can do is we can make a little conditional block. So, we'll engage the PowerUp under these conditions.
So, if (Input.GetKeyDown()) which I'll talk about a bit in a second how that's different from simply GetKey(). KeyCode... I want to map it to the "Z" key on th keyboard. So, if that key is pressed, and we're not currently in a powered-up state, and, of course, if we have any PowerUpMeter to spend. If we don't, then it won't work, so we'll want to make sure that we have more than 0 in our PowerUpMeter. So, under that condition, let's ... Well, we don't know what it'll mean to be powered up just yet, so let's just start off with ... Let's make comments, say, "Start PowerUp mode" Alright. And, "else if." So, we're going to want to cancel the PowerUp mode if we're already in it, and we press the same key. So, GetKeyDown() Do the same thing, KeyCode.Z. And, of course, we have to be powered-up in a PowerUp state for it to cancel. And, again, we'll determine the logic of what cancelling the PowerUp actually means. We're setting it, I guess, to the pre-powered-up state. We'll figure that out later. Alright. Okay, so, you notice we use the GetKeyDown() method instead of just GetKey() so this method returns true once as soon as the key is pressed. And then, returns false even if you hold down the key. So, it only returns true when and if you strike the key, and then if you strike it again, right?
So, this is very useful for trigger-type behavior. If it were otherwise, if we use simply Input.GetKey() and we held down the key, it would, you know, require you to hold down the button just to keep executing this conditional code block. So, we could do that, but I think being in a PowerUp mode should be more established as a trigger-type process rather than actually holding down a button, and then letting go to not execute that code block. So, that's why we used Input.GetKeyDown() So, what we should do now is create some behavior for the first "if" clause where it evaluates as true. So, we know we want to set the IsPowered bool to true to, you know, start PowerUp mode. And, we'll want to countdown the meter, right? Decrement, in other words. So, but we'll want to put the countdown meter in another if statement that counts down only so long as IsPowered is true. So, let's do this: Simply say, IsPowered = true. And, of course, canceling would be tantamount to saying, "IsPowered is false." And now here, we will determine what it means to be in a powered-up state. So, if IsPowered is equal to true, so, just write down the variable name and it'll read as "IsPowered is equivalent to true." Well, we'll want to decrement from the meter. So say, PowerUpMeter --. and have another conditional that's ... Checks if the PowerUpMeter == 0. And, basically, what that should mean is powered-up state should exit. It should be false, so that's pretty simple. IsPowered = false. Pretty logical stuff, huh?
This is not complex. And well, this is less than ideal, but we'll output it to the Debug.Log(), the PowerUpMeter so we can check that the decrement is working fine just like that. And, just to make it clear, the reason why we checked the powered-up state in a different conditional... You may have thought, "Why not just do it in "the part that checks whether or not "we satisfy those conditions to make IsPowered true?" Well, because, remember, this first "get key down," uh, part of the evaluation, it checks to see if the key is just struck down. So, in other words, this block really only executes on that frame, right? If you keep holding down the key, or, you know, if all these other evaluations evaluate as true, it won't continue to execute this code block. It will just execute on that one frame. But, we're going to want to execute this on successive frames, so long as we're in the powered-up state. Alright, so that's why we did it in it's own conditional statement. Alright, so let's run this now and look at the console to see what's happening with the meter. We give the PowerUpMeter a 50 integer startup bonus. So, we'll see how it decrements when we hit the "Z" key.
Sure enough, there we go. And, well, I didn't catch it, but I think the public bool here, it had canceled automatically when it reached zero. So, let's just try that again. Yep, there we go. And, we'll also want to try canceling it ourselves before it cancels. Yep. Yep, works well. Okay. Okay, so, this is working, but there's a problem, as you can see, with this temporary output to the Debug.Log() of the PowerUpMeter. But, we have to do this right now because, well, for whatever reason, the inspector, it won't show us the public static field for the PowerUpMeter. It'll show other public fields, but if it's static, it just doesn't show in the inspector. So, this is less than optimal because, as you can see, it will decrement on every frame and spit out the results to the Debug.Log() and overwhelm pretty quickly. But, you know, this is just all temporary until we can find a way to display the meter, which I think we'll do in the next video. So, before we go to fixing that, now let's go on to considering what kind of PowerUp up we can actually implement here. So, how about we slow down the game? Which, in this case, we would just want to slow down the speed of our cube player, as well as the sphere enemies. And we can do this actually very easily by just referencing the speed fields that we used, remember, as a multiplier of sorts to determine how fast our characters travel. So, simply reduce those fields when in PowerUp mode, else when not on PowerUp mode, put it back to its normal speed, right?
So, let's go to the CubeController script and, while we're at it, why don't we slow down the speed of our characters in general because we know the game is going to get pretty overwhelming pretty quick, right? As we're duplicating enemies at a pretty fast clip. And we want to have a fighting chance when things get hectic. So, let's just change the default Speed to seven for our cube, and, for the sphere, let's make it a little bit slower again 6, .06, I should say And since in the PowerUpManager, we're going to want to reference these fields, we're going to want to make them both public static. Static because we're not going to be really able to access the instance, at least not easily. It's just more easier to make it static as we've been doing so far. So, let's make them both public static. Alright, and now we're going to want to reference them in our little logic blocks here in the PowerUpManager. So we want to do it here when the trigger is activated so we don't keep decrementing the Speed. We only, on that frame, as soon as we engage PowerUp, start decrementing. So, let's say CubeController.Speed equals... Now, let's just go to half Speed. Let's make it cut the Speed in half in PowerUp mode. So, let's say CubeController.Speed * 0.5f. Alright, that should do that. And we'll also want to access the SphereController in the same way. So, actually I'll just copy this and we'll make both the Player 1 and the enemies cut their Speed in half. And, well, when we cancel out of this, we're going to want to double it, right? Go back to its original value. So, let's multiply it by two to double it.
Pretty easy. And here, we'll also want to repeat this when it automatically cancels, right? Okay, so let's run this now and see how it works. Now I can't go into PowerUp state without a PowerUp. Leave PowerUp state, go into PowerUp state. Let it automatically leave the PowerUp state. Yep, seems to be working fine. Alright, that seems to be working. Okay, so our logic works, but it's kind of ugly. In particular, the simulated time change mechanic is being repeated in both conditional evaluations. So, what do you think we should do when we see repetition? That's right. We should consider refactoring it into its own method. So, let's do this really quickly. Let's make a method beside Update(). Call it, private void TimeChange() It takes in a float called speedFactor local to this method that we'll pass in where we call this. And we'll basically take this part right here, and it will allow us to multiply by our speedFactor, which will be different depending on if we're entering or exiting the PowerUp mode, right? And, well, we can also just... You can remove this from there, too. We can put it right in here because we know we're going to want to either enter or exit out of IsPowered states. So, you can just really simply do it this way and say, IsPowered = !IsPowered So, it will have a little switching behavior, you know, built into the bool.
That's why bools are so useful for this state-keeping type of mechanic. And then here, take this fairly large code block, And actually we can just put... I will lose the comment unless I put it after the TimeChange() call here. But, as you can see now, I can put it all on one line of this method call. So, we'll change the time to 0.5, or we'll multiply it by that amount to get half. And here, we'll just multiply it. Multiply it by 2, so we can get back to our original value, right? And same thing here. A little bit cleaner, a little bit easier to read, and I'll just put a comment. Yeah, I'm calling it, "change time." I know that's kind of a misnomer because, actually, what we're doing is changing the speed of the characters. But, nonetheless, it has the effect of changing time. That's how we'll probably be thinking about it. Let's just quickly try that out to see if it's still working correctly. So not powered up, powered up... Again, another power-up, and let it run out. Great. Alright, well, I think we should probably leave things like this for now. I know we can keep refactoring and going on and on with that, but I want to just sort of keep things moving. And, we can always come back when we're closer to finalizing the project. So, alright, well done. We'll end the video here and tackle the next problem in the next video. Thanks.
Lesson 32 - Implementing Powerup State Logic