‫Hello and welcome back.
‫Now we're ready to start handling user input.
‫That means we'd like to press the keyboard keys and move the mouse and click the mouse and see our tank
‫react to that input.
‫Now, in order to do that, we first need to actually get that input and we're first going to start
‫doing that using axis mappings.
‫So let's talk about this.
‫Now here in the project, let's go to edit and project settings.
‫And if we scroll down and select input, then we see our bindings here.
‫And under bindings there are action mappings and axis mappings.
‫We're first going to get into axis mappings.
‫Now you may have some experience with these, but we're going to take a little bit of a deeper dive
‫into what these do and how they work.
‫So we have three of them.
‫And if I click on the dropdown arrow, I'll see here W and SW and these are talking about the W and
‫SW keys on the keyboard.
‫These are assigned to this particular axis mapping, which is called Move Forward.
‫So let's discuss how this axis mapping works.
‫So we saw in The Unreal Editor that we have this axis mapping called Move Forward and it's got the W
‫and SCS assigned to this axis mapping.
‫So what does this mean exactly?
‫Well, in Unreal Engine, we have something called an axis mapping.
‫And axis mapping is something that's processed every single frame of the game.
‫You assign keys to an axis mapping.
‫In our case, we've assigned W and S.
‫Now take a look next to the W key here.
‫In my little screenshot sample to the right, it says scale.
‫And next to scale there's a number 1.0.
‫And you may have noticed next to the SQ, the scale is -1.0.
‫So these are values that will affect that input information.
‫Here's how an axis mapping works.
‫Our axis mapping move forward has the ability to be associated with a function in C++.
‫Now, when it comes to Axis mappings, if we associate a function with an Axis mapping, it needs to
‫take an input parameter of type float so we can create a function on our pond called MOVE that takes
‫a float.
‫We'll just call this input parameter value.
‫Now there's a way to take this function and associate it with our move forward axis mapping.
‫It said that we bind the move function to the axis mapping.
‫So every frame of the game Unreal Engine's input system is going to check to see if we're pressing the
‫W key or the key.
‫And it's going to compute an axis value depending on whether or not we're pressing those keys and every
‫single frame.
‫It's going to call this function that we've bound to move forward and pass that axis value in.
‫Whatever happens inside of that function is up to us as the C++ developer.
‫Now here's how it works.
‫If we're not pressing the W or the Keys, this axis value has the value zero.
‫So the move function that's bound to the move forward axis mapping is called every single frame and
‫the float value passed in is zero.
‫Now let's say we're pressing the W key.
‫The W key has its scale set to 1.0.
‫This means that our axis value is going to be 1.0 and that's what gets passed into the MOV function.
‫So every single frame, the move function is called with a value of 1.0 passed in.
‫Now let's say instead we're pressing the SRC which has a scale value of -1.0.
‫This means that every single frame the move function will be called and -1.0 will be passed in.
‫Now in the case where we're pressing both W and S, then both of these values are added together.
‫So we get the 1.0 from pressing the W key and we get -1.0 from pressing the SRC.
‫Now these both cancel each other out.
‫So if we're pressing both at the same time, the move function will be called with zero passed in.
‫So depending on which combination of keys we're pressing, we'll get a different value passed into our
‫MOVE function and we can do whatever we like with that value, such as use it to move the pawn.
‫We'll talk about actually moving the pawn soon enough.
‫For now, let's just work on actually setting ourselves up so that we can handle this information from
‫the Axis mapping system.
‫Okay, so now that we know how the Axis mapping works, it's time to create a callback function that
‫we can bind to the move forward axis mapping.
‫So I'm going to close project settings and hop back into VS code.
‫So here in VS code, we'd like to create a function that we can bind to the move forward axis mapping.
‫So here in tank H we can create a private function.
‫Now it's going to have.
‫The void return type, and I'd like to call this move.
‫Now it needs to have a float input parameter, and we're going to call this value.
‫So let's take our move function and define it here in Tank.
‫CP I'll stick it here just under the constructor and we need a tank with the scope resolution operator
‫before the function name.
‫So we have this move function and we're ready to bind it to our move forward axis mapping.
‫And that is done inside of a function called setup player input component.
‫That should sound familiar.
‫In fact, if we open our explorer and go back to Base Pont H, we can scroll down and see in the public
‫section the function setup player input component.
‫We'll see that this is an override of an inherited virtual function.
‫Now the base spawn class does not really need to set up any inputs, and that's what this function is
‫for handling input from a player.
‫Now, our base bond class doesn't need to handle input, but our tank class does.
‫So what we can do is take this function out of base pond h but I'm going to copy it because we need
‫it in tank.
‫So copying this function, I'm going to come over to Tank H and here in the public section I'm going
‫to paste it.
‫And since we don't need it in base pond, I'm just going to remove it from the base pond class.
‫And in fact I'm going to go into base pond CP and remove it from here as well.
‫So let's go ahead and delete setup player input component from Base Pond.
‫CP And now it's no longer in the base pond class.
‫So let's go ahead and save our changes and close base Pond H and CP.
‫And now we have setup player input component declared in Tank H, but we also want to define it and
‫tank.
‫CP So here in Tank.
‫CP I'm going to add the definition just above the move function.
‫So this is void and it's a tank set up player input component.
‫Now let's go back to Tank H and see what its input parameter type is.
‫You'll see that it's forward declared here inside the parentheses.
‫This is something you can do if you want to forward, declare a class type in a header file.
‫So it's forward declared here and we need this you input component pointer type and the parameter is
‫called player input component.
‫So we need this input parameter in tank.
‫CP So in the parentheses for setup player input component, we're going to have a U input component
‫that's a pointer and it's called player input component.
‫So now the function signature matches that in the function declaration.
‫Now back in the CP file, let's give this function a function body and we're overwriting this function
‫and it's a good idea to call super set up player input component.
‫Now, since we're calling the parent version of setup player input component, we have to pass in an
‫input of type you input component.
‫We're going to pass in the input parameter to this function here.
‫So this way the parent class will call its version.
‫Now the base pond tank is not implementing this function.
‫We just removed it.
‫But the parent class to base -- will call its version.
‫And whenever you override a virtual function like this, calling the super version is a good idea.
‫So we don't miss any functionality implemented in the parent version.
‫So why are we doing this?
‫What is setup player input component good for?
‫Well, one of the things it's good for is binding functions to access mappings.
‫We'd like to bind our move function to the move forward axis mapping.
‫And we do that here.
‫We do that using this input parameter player input component.
‫That's what this object is designed for.
‫We take the player input component and on this pointer we use the arrow operator to access a function
‫called bind axis.
‫Now Bind Axis takes a few input parameters.
‫The first is a string literal, which means we're going to use the text macro.
‫Now what do we put in the quotes?
‫We put the name of the axis mapping.
‫We saw in the editor that this axis mapping is called move forward.
‫So we're choosing that axis mapping to bind to the second input parameter.
‫This is going to be a pointer to the object where binding the function for this is a pointer to the
‫instance of the particular class where n and since we're in the tank class, this will point to the
‫instance of the tank pawn in the game.
‫Now the third parameter is the address of the function we're binding.
‫So we have a tank move.
‫Very important that we need to fully.
‫Qualify the function name with the name of the class.
‫And right here in front of the function name, we need the address of operator.
‫Now, if you're not familiar with doing something like this, this is simply taking the address of a
‫function.
‫Functions can have addresses just like variables can.
‫So using the address of operator is a way to pass functions into other functions.
‫So that's why we need that address of operator.
‫So we have our function call to bind access.
‫Now you're probably noticing the IntelliSense error pointer to incomplete class type you input component
‫is not allowed.
‫Now we know what can cause this.
‫For one, it could mean that we need to include a header file.
‫Another possibility is that it's a false error.
‫You can easily find out by compiling, so let's attempt to compile.
‫We'll see that we have a successful compile.
‫So we know this is a false error.
‫But again, if you want, you can add the include just to remove that.
‫So it's not bothering you.
‫Now we know that the class type that it's complaining about is you input component.
‫So here's you input component in the documentation and here's the include.
‫And if we add this up here at the top of the tank CP file, we'll get rid of that pesky false error.
‫And again, because these have the pragya wants include guards, we know that input components is not
‫going to be included more than once and there go the squiggles they're gone.
‫So now we know this move function will be called every frame and value will have a particular float
‫value depending on whether we're pressing the W or asks.
‫Now, simply knowing that the move function is bound to move forward is not quite enough.
‫As developers, it's nice to have some sort of confirmation that things are working.
‫So what I'd like you to do as your challenge is to use YUI log in the MOV function to print the value
‫that's being passed into move that float called value.
‫So use percent f in uiy log to log the value of the float value to the output log and then play test
‫the game and press those keys and see what you get printed out to the log.
‫Pause the video and add this to the move function now.
‫Okay.
‫So here in the mov function, i'm going to add a uii log.
‫And this can be log temp warning.
‫And for the text macro.
‫I'm simply going to put value percent F and value.
‫Now that's okay.
‫If you used a different verbosity or warning type, if you know how to do those things.
‫That's totally fine.
‫I'm just going to use a warning here and I know you've used things like percent se and formatted your
‫log with a string value.
‫Percent F, if you're not aware, is how you can format your UI log with a float value.
‫So let's compile this and back in the editor, I'm going to open up the output log and press play and
‫check it out where spamming the output log with countless messages.
‫Now I'm going to click in the viewport and press the W key.
‫There's my value of one I'm going to release.
‫It's back to zero.
‫I'm going to press the key and it's negative one.
‫And if we press both at the same time, we get zero.
‫And so it's exactly as we expected.
‫Perfect.
‫All right.
‫So in this video, we've set up our pond to handle some user input.
‫We talked about access mappings and we bound our move function to the move forward access mapping.
‫We then printed that access value using YUI log in our MOVE function, but we'd actually like to move
‫our tank rather than just print some values to the output log.
‫So in the lectures to come, we're going to set it up so that we can actually start moving our tank.
‫I'll see you soon.