When selected, we get a new dropdown menu titled “Control Type.” And here, we have a large list of all possible input types that a player can perform. Selecting a control type will limit the type of bindings displayed. The “Button” action type will only permit using “ButtonControl” inputs, like keys on a keyboard or the face buttons on a controller. And Pass-Through has the same input options as Value, except Pass-Through is missing a feature called “Disambiguation.” Disambiguation essentially chooses which controller is in control if there is more than one connection at a time, and it does so by measuring which has the largest changes occurring.
We want our character to be controlled by the left stick, so let’s select “Pass-Through” or “Value” as the Action-Type, and we actually have a few options for control type, mainly being “Vector 2” or “Stick.” Let’s go with “Vector 2”. When we press on our empty Binding, we seein the “Properties” menu that our “Action” submenu switches to “Binding.” Binding has an empty selector titled Path, which is the input. What’s cool about Path is we can either type in the name of the input we are looking for, like “Joystick,” or we have this“Listen” button which, when pressed, will save any inputs from a device and list them as options — making it faster to find the exact input we are looking for. For today, we are going to be using a NintendoSwitch Pro controller, which is connected via Bluetooth. But this also works with PS4 and Xbox Controllers and more.
Button and Spin
Now, Unity should automatically detect the controller. To be sure this is the case, we can go to the window, Analysis, and Input Debugger. In the new window, we should see our controller, and we should see a constant flow of input detection. Once confirmed, we can use the “Listen” button and spin the left stick around to find the “Left Stick” Input Binding. This binding is a blanket input binding for all supported gamepads, rather than specific to the Pro Controller or the PS4controller. Let’s add our only processor for today: stick deadzone. This will set any input value less than the minimum to 0 and set any value greater than the max to 1! And we’ll cover the rest of the processors in the future! Let’s create one more Action, a title “Run,” set it as a “Button,” and then map it to the left shoulder button. We’ll add the “press” interaction and select “press and release” from the dropdown. This will trigger the press’s action and on the release, which will be helpful in our code.
We’ll have our players hold the left bumper when they want to run. Great! The last thing we need to do with our input is to save and create a class. Let’s select our input asset and take a look at the inspector. Here there is a checkbox titled “GenerateC# class.” Let’s check this and hit apply. This will make it easier for us to access our actions in our code. Entering play mode, we’ll see that what we’ve done thus far with our new input system has not impacted our character at all. Let’s begin by declaring a handful of variables. Let’s start with what we are familiar with from previous tutorials, declaring an animator variable of type “Animator” and two integer variables titled isWalkingHash and isRunningHash. In our start function, we can set the animator to the Animator component using the GetComponent function and passing in Animator as the parameter. Right below that, we can set our two hash variables using the Animator.
Walking and Running
StringToHashfunction and passing in their respective parameter names — be sure to use your own parameter titles if you titled them anything different. Ok cool! Next, we’ll start to set up our movement logic. In a new function titled “handle movement,” we will create two new local boolean variables, walking and running. We’ll set these equal to the result of the animator.GetBool, passing in each respective hash as a parameter. At this point, we can begin coding logic using the new Input System. Scrolling to the top of the file, we have the default Namespace imports, signified by the “using” directive. Basically, what this does is allow us to access other classes, like the InputSystem! So we will add “using UnityEngine.InputSystem”! With this, we can now access the C# class that we generated when we applied the checkbox from the inspector of our input asset. Directly below our declared hash variables, we can add a variable “input” of type “PlayerInput.” Note, this should be whatever you titled your input asset because that’s what your C# generated class’s title will be. Next, we will set our input variable, but we will do so in a new function. The awake function is similar to Start, but it’s called even earlier: when the object that the script is attached to is initialized, not when it’s enabled. Here we will set input equal to a new instance of PlayerInput, which we created for our input actions when checking the box in the inspector.
Doing so allows us to access our action Map and Actions directly! In programming, we have “Listeners,” which means that our code is waiting for some event to occur. In our case, we set up earlier actions waiting for a joystick to be moved and wait for the left shoulder button to be pressed. When either of these happens, our code will respond! And they will respond by providing accurate controller values to what is known as a callback function! Let’s set up these callback functions. Now that we have our input variable set inAwake, we can access our action maps and actions! Typing input.CharacterControls.Movement weare now accessing our movement action. This action has a list of functions available to it. We will use “performed” by adding .performed. The current context contains information on the current state of the callback.