How to use Unity's Input system?
- Abhishek Jathan
- Oct 24, 2024
- 5 min read
Alright this is going to be a quick and dirty way to use the input system package. Let's go.
Step 1 : Installation
Open the package manager and install the latest version of Input System. Obviously.
Step 2 : Create an input action asset
In the project window, right click -> Create -> Input Actions. Let's call this new asset InputSystem.
Now select this new asset you just created, check the Generate C# Class in the inspector. Click Apply. We'll get to why we need this, but a few steps later.
Step 3 : Create action maps and actions - Part 1
Open the asset. You'll see something like this. Now you'll see 3 divisions. I like to keep Auto-Save button enabled, but that's up to you, if you want to manually save there is a Save Asset button right next to that button as well.
Click on the + in the Action Maps section. Now let's call this Action map Player for now. A default action will be created.
Advanced Pro tip : You can rename an Action Map or an Action by clicking on them twice.
So, now we click the little plus in the action division, 3 times. Now we have a total of 4 actions.
Now we can rename these actions to match the most basic of actions most games have.
Forwards
Backwards
Leftie
Rightie
Yet another advanced Pro tip : The little triangle next to the action expands it.
Step 4 : Create action maps and actions - Part 2
Now, my dear reader, you might have noticed that there's <No Binding> written under each of the action.
This is where things get serious. Ok, not really.
Remember the 3rd division in this big dialogue box? Thats like the inspector but for actions and the action maps.
Click the binding under Forward action.
Now in the 3rd division click on the drop-down list called path.
Go to keyboard -> By Location of Key (Using US Layout) -> W
Now the Forward action is linked to the W key.
Similarly, if you're working on a game that supports both keyboard and gamepad, you can add more bindings under the same action. For example, the attack button can be mapped to the left click button on the mouse, and the X or O button on a PlayStation controller, or A or B on an Xbox controller.
The reason this is cool is because now you don't have to write custom code for each controller or input device. This makes life a little easier.
Now let's add more buttons for each action.
So now this is what it will look like after all the actions have been mapped to respective bindings on the keyboard.
You know what, lets add some more bindings
Now, make sure you save the asset by clicking Ctrl+S or by clicking the Save Asset button
Step 5 : Scripting - Part 1
Alright, now we can write some code.
Let's create a new scene and create a square sprite gameobject.
Let us also create a C# script called BoxControls.
using UnityEngine;
using UnityEngine.InputSystem;
public class BoxControls : MonoBehaviour
{
//Instance of the input action c# script that is automatically created
//when generate c# class checkbox is enabled
InputSystem inputSystem;
//Variables for this simple demo to work
public Vector3 movement;
[SerializeField] private float moveSpeed = 5f;
private void Start()
{
inputSystem = new InputSystem();
inputSystem.Enable();
//If you noticed the order of access,
//its from Input actions class -> Action Maps -> Actions
inputSystem.Player.Forward.performed += OnForward;
inputSystem.Player.Backward.performed += OnBackward;
inputSystem.Player.Leftie.performed += OnLeftie;
inputSystem.Player.Rightie.performed += OnRighty;
}
private void Update()
{
transform.position += movement * (moveSpeed * Time.deltaTime);
}
public void OnForward(InputAction.CallbackContext context)
{
Debug.Log("Forwards");
movement.y += 1;
}
public void OnBackward(InputAction.CallbackContext context)
{
Debug.Log("Backwards");
movement.y -= 1;
}
public void OnLeftie(InputAction.CallbackContext context)
{
Debug.Log("Leftie");
movement.x -= 1;
}
public void OnRighty(InputAction.CallbackContext context)
{
Debug.Log("Righty");
movement.x += 1;
}
}
Now, this is not the best way to move something, simply an example. Chill.
Step 6 : Scripting - Part 2
Now if you attach this script to the sprite that you created in the previous step, you can set the speed of the sprite using both the arrow keys as well as WASD keys.
Woohoo! Now you're using the new input system.
Now let's get into the code snippets
private void Start()
{
inputSystem = new InputSystem();
inputSystem.Enable();
//If you noticed the order of access,
//its from Input actions class -> Action Maps -> Actions
inputSystem.Player.Forward.performed += OnForward;
inputSystem.Player.Backward.performed += OnBackward;
inputSystem.Player.Leftie.performed += OnLeftie;
inputSystem.Player.Rightie.performed += OnRighty;
}
public void OnForward(InputAction.CallbackContext context)
{
Debug.Log("Forwards");
movement.y += 1;
}
I know the indents are off. Totally aware. Not gonna fix it.
Now, if you are slightly confused about the "+=", checkout this article.
Think of it this way:
Instead of writing code that constantly asks 'Is this button pressed? Is this button pressed?' (like an impatient kid on a road trip), the new Input System works more like a smart doorbell.
When someone presses the doorbell (or in our case, a button), it automatically notifies you - 'Hey, someone's at the door!'
In technical terms, each button binding has an associated 'performed' event. We simply tell the system 'When this button is pressed, run this specific piece of code.' It's like setting up automatic responses to specific actions.
This event-based approach is not only cleaner and more organized than the traditional polling method (the constant checking), but it's also more efficient - your game only responds when something actually happens, rather than continuously asking if something happened.
Checkout this post on Event based programming for more clarity.
So, the += symbol is for setting a subscription for an event, so if the Forward action is performed, the OnForward method is called automatically. You don't need to constantly check the input with an if condition.
You can also use lambda functions to call regular methods that don't need the callback context. Example : inputSystem.Player.Forward.performed += ctx => OnForwardButtonPressed();
Conclusion
The Input System is a powerful tool that goes way beyond what we've covered in this post. While this guide helps you get your hands dirty, there's a whole bunch of features to explore - from complex action maps to dynamic rebinding and different types of interactions ( Hold, tap, multitap )
The reason I wrote this article was because the official quick start guide was not very helpful, and a lot more complicated from a beginner's perspective. There are several ways to use this system but this is the way I prefer to use it, because it was pretty easy to work with. (Personal Opinion)
For all the workflows checkout this official document from unity.
Thats all Folks!
References:
Comments