Modularity Boost with New Input System in Unity
Get started with the new input system to add cross-platform support in your games with a modular approach
Table of Contents- Introduction
- Input Actions
- Implement Player Movement
- Fire a Projectile
Unity announced a new input system around 2018. It had been in a preview state for a long time and changed a lot over time. The first stable version is released in 2020 but still hasn’t replaced the old input system by default.
So why Unity developed a new input system? What is the problem with the old one?
Well, the old one did a job for some time but the increasing number of devices and different kinds of controls made it quickly outdated. Also, It’s not a modular system due to its architecture.
A lot of people opt for 3rd party assets when it comes to cross-platform support and features like in-game input mappers.
The new input system promises to solve all these problems in a modular and customizable package.
In this piece, we’ll go through how to get started with the new system without drowning in detail. We’ll see how to implement some simple mechanics like walking, shooting, etc.
You can download the final version of the project material from my Patron page. You can also complete the tutorial without it but you will need to configure everything for yourself.
At the time of this writing, I’ve used Unity 2020.2.1f1 and Input System 1.0.1.
Open up the package manager through the
Window/Package Manager menu once your newly created project starts. In the Package Manager window change
Packages: In Project option to
Unity Registry. Find and select the
Input Manager package in the list then click the install button. After a few seconds, you will see a warning window about enabling the new input system and restarting the project. Just click yes and wait for your project to restart.
That’s it. Now we can start using the new input system!
Before diving into any feature implementation we need to set up a scene.
Open up the
SampleScene in the
Assets/Scenes folder. Next, create a 3D terrain object in the scene as the ground and then create a 3D cube object in the active scene and name it
Then create a C# script under the
Assets/Scripts folder and name it
PlayerMove. Open this newly created script in your IDE and paste the below boilerplate code into it. Save the file and add the
PlayerMove script to the Player game object as a component. This component will add two more components to the Player game object: a RigidBody and a Player Input.
Please refer to official documentation about adding components to game objects if you have any questions.
The Player Input component is where the magic happens. It needs an input actions asset in order to work.
An input actions asset is where we can define actions like move, look, fire, etc., and then assign keybindings for those actions. While it’s possible to create everything from scratch there is an option to create a pretty useful default one.
To create a default input actions asset, click on the
Create Actions... button in the Player Input component. Name it
Actions and save it under the
Assets/Settings/Input folder. Now we have an input actions asset assigned to the Player Input component.
Let’s look into this created input actions asset. Double click on the created asset to open it up in the Input Actions window.
We will use this window to setup all about input mappings.
On the left side, there are Action Maps. These are different profiles for different action groups. For example, we can create an action group for the player character and then create a different group for vehicle driving. Also for the UI actions.
In the middle, there are
Actions for the selected action map. These are the actions that a player can do in the game. For example, moving, jumping, shooting, opening doors, etc.
Each action has its bindings. We can bind multiple controls under one action. For example, we can bind
WASD keys for and the left stick for gamepads to move action.
On the right side, there are properties for the selected action or binding.
We can define the action type here. Is it a value like a mouse position or a button? Depending on the action type we can add interactions like tap or multi-tap. It’s also possible to add processors. For example, we can add
Vector2.Normalize as a processor in case of a
Vector2 action type. This way we’ll get the normalized value when we read the action value in our code.
Implement Player Movement
Ok, now it’s time to get our hands dirty with coding. Let’s implement some basic player movement with the current setup.
First, add the following code into
Next, open up the
Player Input component and change
Behaviur option to
Invoke Unity Events. This will add an
Events option to the list. Expand the
Events and then
Player options. You will see a list of action events that are defined for the
Player action map inside the input actions asset.
Now it’s time to connect
OnMove method in
PlayerMove script to Move event in here.
+ button under the
Move action and then drag the
Player game object from the scene to the object section here. After that, you will be able to select the
PlayerMove.OnMove method from the dropdown menu.
That’s it. Now you can click on the Player button and move the player character with a keyboard or a gamepad!
In the previous example, we’ve used Unity Events with the Input System by changing the Behavior option. It’s a great solution for decoupling your components and modularity.
There are also other behavior options. These are all code-driven. There might be use cases for these in your project or not.
As a starting point, I would recommend you to stick with the Unity Events option. It’s modular and you can control the dependencies from the editor. If you’re still curious about the other options please refer to Notification behaviors in the official documentation.
Let’s talk about the event code a bit.
If we look at the
OnMove method in the
PlayerMove script it takes a parameter:
InputAction.CallbackContext context. This contains a lot of information about the action.
Then we’ve used
context.ReadValue<Vector2>() to read the direction value for the movement. You might wonder how to know what kind of data we’ll get from this method. Is it just Vector2? Well, no.
If we open the Input Actions window again and select Move action in the Player action map then we’ll see action properties on the right side. The Action type is
Value and the Control Type is
Vector2. This is how we can define what kind of value we’ll get from the
If we change the Action type to for example to
Button then it’s a different story which we will cover in Fire a Projectile section.
Fire a Projectile
In terms of input handling, firing a projectile is not that different than the movement. There is already a Fire action in the created input actions asset. All we need to do is create an
OnFire method and add it to the Fire event in the Player Input component like how we’ve done it for
OnMove in the previous example.
Create a new script called
PlayerFire and paste the below code into it.
Add this script to the Player game object in the scene. Connect
OnFire method to Fire event in PlayerInput component. Notice the serialized field
projectilePrefab in the script. In order to fire a projectile, we need to create one.
Create a 3D sphere object in the
Assets/Prefabs folder as a prefab and name it
Projectile. Please refer to official documentation about creating prefabs. Add a Rigidbody component to it and uncheck the Use Gravity checkbox. Add it to the
PlayerFire component in the editor.
That’s it. Now you can click on the play button and keep the left mouse button pressed to fire projectiles.
If we look at the
OnFire method we will notice that it’s a little bit different than the
OnMove method. We don’t read any values here. Instead, we read the action phase and perform different actions respectively.
That’s because the fire action type is a button. In the case of a button, all we care about is if a button is clicked, holt, or released. In the performed phase, we start the fire and stop it in the canceled phase. We can fine-tune these phases in the Input Actions window.
So far we’ve seen the fundamentals of the new input system. We’ve seen the Player Input component, Input Actions, and how to use these in our game by moving the player and firing projectiles.
Now it’s your turn. Try to create a jumping behavior for example. In the default actions asset, we don't have a Jump action. Configure it using the Input Actions window and implement a simple jump behavior for the character.
The new input system for Unity is great. I especially love how modular it is. It’s also pretty easy to implement features like control mapping, touch controls, and so on.
Check out my Patreon page to support me and see some cool offers!
Emre Yilmaz is creating game development content in Unity. | Patreon
Hello, and welcome! I'm Emre, a.k.a. emreloper. I build indie games and create educational content about game…
Stay tuned for more content like this!