I’ve used stuff similar to Unity’s New Input System in VR projects using the XR Interaction Toolkit so I figured it’s time to learn the New Input System and convert the 2d Space Shooter game I’ve been working on before I go any further with it.
As shown in Unity’s Installation Guide, First go to the Package Manager in Unity and search for Input System, click Install and it will prompt you enable the new backends and restart, choose Yes.
Once Unity restarted I continued by creating an empty gameobject in the Hierarchy and named it Input_Manager, clicked add component and added a Player Input Component. I also created a script named InputManager and attached it, this I used later to make 2 ActionMaps be enabled at once instead of the default 1. Instead of adding the Player Input component to my player I added it to this object so it can still be accessed when the player dies.
On this component click Create Actions… button and it will ask you where to save the .inputactions file, I named it “Controls” and saved it in a folder named “InputActions” that I created in my project’s Assets folder. (This step is found in Unity’s Quick Start Guide)
This creates an Asset pre-populated with a default set of Input Action Maps, Input Actions, and Input Bindings for Player and UI.
Change the Behavior option to Invoke Unity Events
Invoke Unity Events uses
UnityEvent in the same way the Unity UI does. Unity displays an event for each Action that is linked to the component. This allows you to directly wire in the target method for each event.
Each target method takes an
InputAction.CallbackContext argument that gives access to the Control that triggered the Action and the Action's value.
I now opened my Controls InputActionAsset and selected my Move action in the Player action map and changed the Action Type to Value and Control Type to Vector3.
Next I selected the Fire action and clicked the + next to it to create another binding, you can either click listen after selecting the path dropdown and hit the space key or click Keyboard and then search for Space key, I also checked the box for Keyboard&Mouse control scheme.
Next instead of adding new actions to my Player Action Map for my Restart level and Exit the game functionality I created a new one name GameManager since that is the script I have handling those features.
In the GameManager action map I made a new action named “Restart” and another named “Exit” and binded them to their respective keys. Esc key for exit and R key for Restart.
One last step we need to do before heading to our code, go to your EventSystem gameobject in the Hierarchy(If you’ve created any UI elements or canvas Unity will create an EventSystem object), it will show an error as seen below, just hit the Replace with InputSystemUIInputModule button and Unity will fix it.
Now I went to my Player script and added the namespace for the new input system at the top.
I want my Player class to have access to the Player Actions interface so I added
It will underline and give you an error, just click the little icon and implement, it will add the required methods from the interface to the bottom of your script.
For my movement I originally was checking for input in my Update method with my CalculateMovement() method that looked like this…
Everything in there will stay the same except for the direction variable which I need to be able to access outside of this method and set it with my OnMove method. So I created a private variable named _direction.
In my OnMove method I access the current value as a Vector2 and assign the value to my _direction variable.
Now for my FireLaser() method instead of checking for input in update I just call my FireLaser() method in the OnFire method each time space key or whatever other button is binded to the Action is pressed/performed.
This is how it was before new input system…
How it looks with the same logic using the new input system
Finally, in my GameManager script which is in charge of restarting or exiting the game I made the following changes..
This is how I was handling it in my Update method before the new input system…
Now I added the namespace at the top and have it inherit the IGameManagerActions interface, same steps as in my Player class.
All in all the new input system is much more powerful as you can setup multiple control schemes and use the same code instead of more lines checking for input from different controllers for different systems.
There are also different ways to access the info from your Actions but I found interface inheritance to be the easiest. You can read more about it in Unity’s manual located here.