 Before we do anything else, let's handle some input from the keyboard mouse and gamepad so that we can, in our future demos, make them more interactive. And here we have the scene we left off with. We have our cube, our sphere, and our manager. The manager has a script with a cube and sphere component hooked up for the cube object and the sphere object respectively. Let's go look at that script. And here are those properties. And in our update, we're using the input class, which is a class we don't instantiate. It just has a bunch of static properties and methods for us, including any key property, which is a Boolean and any key down in a frame where any key on the keyboard or any button on the mouse or any button on a gamepad, a plugged in gamepad, if a button is pressed initially for that frame or even just held down, this will be true. Any key will be true in that frame, in that update. But then any key down is only true when a button has been pressed initially, not when it's still being held down. So to see this in action, when any key is true, we're going to log out any. And time dot time, that's the number of seconds that have elapsed since the start of the game. And also to just make this more visual, we're going to take our cube and translate it by three units per second on the x-axis. And any key down, when that's true, we're going to print out down and the time and move our sphere. So here, let's see what that effect looks like. And first, just notice the objects and we'll look at the log. So here, I play the game and it doesn't really matter. I need to give focus to the window so I'm going to just click in here with my mouse. And I'm going to hold down the mouse button for like a second. So here, I'm holding it down and I'm just going to keep holding it down. As long as I keep holding it down, that box is going to keep moving. Notice the sphere only moved the one time. I released, I'm going to just tap the button again, tap it a couple times. Initial tap of the mouse button, the sphere is moving down 0.5 units. And the box is moving just a little bit. But if I click and hold, the box just keeps moving. But notice the sphere only moves in that frame where I've initially tapped the button. Anyway, so let's restart the game and let's look what happens in the log. So I'm just going to hit the mouse button and hold it for a second and release. So click, release. In the frame where I initially clicked, both any key and any key down, they're both true. So we see printed out any and down for that initial frame where I clicked. But then all subsequent frames, the one immediately after and all the way down through here, those are frames where only any key was true. So we don't see any, we don't see down. Any key down is only true for that initial frame where we initially hit the button. So that's any key and any key down. Let's look now at get key and get key down and there's also get key up. The get key method, you pass in a key code. Key code is this enum type and so there's key code.g, key code. If you were here, just look at the code completion. So there's basically a code for all possible codes on your keyboard. Also kind of surprisingly, despite the name get key, it also applies to like joystick buttons and also even mouse buttons, as we'll see in a second. But anyway, so let's just go back to g and this is going to be true when either initially we've pressed the g key or we're still holding it down. So in any frame where we're pressing g or holding it down, this will be true. Get key down on key code g, that'll only be true in a frame where we initially pressed g, get key up, that'll only be true in the frame immediately after we release the key. And here's just another example of get key down where the key we're looking for is left shift. So this is true in a frame where the user has initially pressed left shift. Okay, we'll put now left shift down. So let's just see this action, save my code. And let me hit play. And when I click in the window, now we're not seeing anything just from clicks because we got rid of the detection for any key and any key down. We're not using that anymore. Instead, we're looking specifically for g. So I'm just going to tap g real quick, see what we get. So first thing that happens in one frame is get key and get key down. Those are going to both be true. So we first see this, this is from get key and this is from get key down. And we're going to keep holding g for some number of frames and that's why we see g printed out repeatedly. But then at the very end, there's get key up. And notice the time on get key up and the last on g. This is 13.104, this is 13.111, so this is the next frame. So when we press a key and release it, get key up and get key. They're not going to be true in the same frame for a single key press. I think it actually is possible that a user can actually release a key and press it fast enough that conceivably get key and get key up would both be true for the same key in a single frame. Like that can happen, but it'd have to be really fast or your frame rate would have to be quite low. I haven't been able to reproduce it, but my frame rate's pretty high here, so. And also in our code, we were looking for left shift on get key down. So let's see that in action, replay the game. And I'll tap left shift a couple times, one, two. And if I press it and hold it down, notice there's just the one logging message because it's not looking for get key, it's looking for get key down on left shift. As I mentioned, the name get key is really actually misleading because it can query not just keys on a keyboard, but mouse button presses and joystick button presses. And we have key codes for joystick buttons and mouse buttons. So this is here detecting if we have a get key down on joystick button one. Here for mouse zero, that's the primary mouse button, the left mouse button. That doesn't mean you don't have it configured for a left-handed person. And notice here, this is joystick one button one. So if we just look at the code completion, there's joystick one button zero. The full set of buttons for joystick one is the full set of buttons for joystick two, three, four, five, six, seven, eight, up to eight joysticks. But then there's also the full set of buttons for an unnumbered joystick, as we're using up here. There's no number after joystick here. The distinction is that this is querying a button on a specific joystick. Whereas this is querying inputs on all of your joysticks. So if you have a bunch of joysticks plugged in and button one is pressed on any of them, then this is gonna be true. And that's just more convenient for single player games where maybe the user has multiple game pads plugged in and you just want them all to work. And that kind of makes sense for single player games. But as soon as you have local multiplayer, you're gonna wanna distinguish between multiple game pads. So you're gonna have to start querying for specific joysticks. So you can distinguish input from one player and another, of course, right? So let's see this code in action. I'll play the game and I'm gonna focus on the window. When I do so, it should give us the mouse event. Yep, and it's just a discrete mouse down. So even if I hold the button, we don't see initial stuff printed out. And I don't have my game pad plugged in, but I'm going to turn it on right now. Wait a moment, and it should be detected in a second. And yeah, we get the message in the console saying it's been reconnected. And I think button one is B on an Xbox controls. I'm gonna hit B. Yep, there we go. And I just tapped it once, notice that we got the two messages printed out because both joystick button one and joystick one button one, both of those are true. Because it happens that the one joystick I have plugged in, I think they're automatically numbered starting from one, as you would expect. So the game pad I have in this is currently joystick one, but we're also checking for input on any joystick with this key code. And so both of these are true and we're getting both messages printed out for one tap of B. There's an overload of get key down, and also get key and get key up, where instead of a key code, it'll take a string. And the string specifies the name of the key or button. And the expected names are documented here in the manual under conventional game input in the creating gameplay section. So here, for example, like down, that's the down arrow. If you want like right control, that's right control with the space in the middle or case. So it's looking for these strings. Honestly, there's really no reason for this method to exist, because you might as well just use the key codes, which are both more convenient and less error prone. But these key and button name strings, they are relevant because you use them in the input manager for setting up so-called virtual axes, as we'll talk about very shortly. But otherwise, I wouldn't use them in your code. Similarly, there's also get mouse button down and get mouse button and get mouse button up. And for those methods, you specify the mouse button you want to query just by its number as an integer. But similarly, there's no real reason to use these methods because you can always just use get key down with the appropriate key code of like say mouse zero. And this would do the exact same thing. So I wouldn't bother with these methods either. Now, as we've seen the get key methods detect discrete key actions of the user pressing, releasing and holding them down. And that's typically what we want for gameplay interactions. If we want to get typed text from the user, we could use these methods, but it would be very awkward. Like for example, if we wanted to test when the user types an uppercase G, then we'd have to query in that frame. Well, on key down, did they hit G? And are they currently holding down left shift? So we'd have to test for both of these events. And then we'd have to repeat this logic for every other possible key of what they might type. So it's a really awkward way to get users type text. Also, this logic wouldn't really be exactly right because it wouldn't account for auto repeat. Auto repeat is the behavior where you usually expect as a user that if I like hold down a key, after a pause, it'll start repeating automatically a certain specified rate. And we could probably get that same effect using these methods in our code. It would just, again, be very awkward, so we'd prefer not to have to do it. Instead, what we probably want is input dot input string. This returns a string of all the characters the user has typed since the last update. So here in our update method, we're going to grab that as text. And for the case where text is not equal to empty string, where it's not nothing, then we're going to just print that out. So let's see this in action. I'm going to play the game, refocus the keyboard, and I'll type a few characters. And I'm typing pretty quickly. And there we go. So if you type fast enough, it's possible you can get multiple characters within frames. In fact, if I just slam the keyboard, like four keys at once, let's see what happens. We just need to refocus, slam the keyboard. Yeah, so I actually got all four within a single frame. This will depend on your frame rate. The faster you're going, the less likely that's going to happen. And also notice that if I hold down shift and start typing, then it correctly gives us uppercase characters. So if you want to accumulate between frames what the user is typing into a single string, as we probably do, here's one quick example. We're going to use this message property, which we're going to have to add to the class so that it's preserved between updates to string. It's called message. And down here we are going to print out the accumulated message. So each time through we're taking the text, read for that frame, append it to message. And we're going to print that out as well as the text for that frame. So let's see that in action. I'm going to type out hello world. And there it is at the bottom. And I'm just typed hello close enough. Each frame I was only typing fast enough that it registered a string with a single character. But each frame I'm accumulating that in our field message. So that way we can get a user's typed text.