In this article we’ll look at how we can use Unity’s new Input System for Touch controls.
Using 2D Vector Composite for Movement in the New Input System with Unity 2021
First, we need to create our Input Actions asset by right-clicking in the Project pane, Create > Input Actions.
Using 1D Axis Composite for Rotation in the New Input System with Unity 2021
In this article, we’ll use a 1D Axis composite for our Rotation action to rotate the player game object.
Converting the Old Input to New Input
To put it bluntly, we’ll be skipping this as we’ve covered implementing keyboard/mouse input with the new Input System in previous articles.
Granted, those articles are related to 3D movement but 2D movement is actually even simpler.
Since movement in this prototype is simply left and right (A key or D key), you would use a 1D Axis Composite to implement.
For a production project, I would suggest, ideally, starting with the new Input System or converting to the new Input System for any current input logic before moving on to using the new Input System for Touch input.
Integrating with Legacy Input for Player Movement
In order to integrate with the legacy input for player movement, we’ll need to pass in float values to the Player class for the appropriate Touch input.
We’ll use one of the new Touch buttons to trigger PerformJump() while the Touch joystick will be used for movement.
Creating the Input Asset for the new Input System in Unity 2021
To create the Input asset, simply right click in the desired folder of the Project pane, then click Create > Input…
Setting up the Input Asset
I’ve covered creating an Input Asset in a previous article, please refer to it as needed.
For this project, I’ve simply named the Asset as “InputAsset” and created an Action Map called “Character”.
The Player Input Component
While we don’t have to use a Player Input component with the new Input System, I’ll be using it for this project.
Create an empty gameobject which is named “InputManager” in the Hierarchy.
Create a new C# script called InputManager and assign it to the newly created InputManager gameobject.
On the InputManager gameobject, add the “Player Input” component as shown above.
Assign the InputAsset to the PlayerInput component and Default it to the Character Action Map.
Set the Behavior as “Invoke Unity Events”.
Once you have created Actions for the Character Action Map, the Player Input component will display corresponding fields for each Action under “Events”.
We’ll get to that in a minute.
Setting up the HUD UI
We’ll need to add 3 UI images to the canvas we used in previous articles for the Shop dialog.
One image for our joystick and two for our buttons.
Adding On Screen Components to UI Elements
We’ll need to add the On-Screen Joystick and On-Screen Button components to the UI image elements they correspond to.
Set the Control Path for the Joy_Stick element to be an Android Joystick.
You could also use a Gamepad’s joystick or D-Pad if you prefer.
Then set the Behavior as “Relative Position With Static Origin”.
For the A button element, it has been assigned to the Left Mouse Button as that is currently what controls the player’s attack.
And for the B Button element, this has been assigned to the current jump button which is the Space key.
Create the HorizontalMove Action and Bindings
As shown above, we need to create a new Action to represent our horizontal movement.
Give it a 1D Axis with the bindings matching our UI Joystick’s Control Path of “AndroidJoystick”.
NOTE: I ended up using Action Type “Value” rather than “Passthrough”, though the results should be the same or similar.
Modifying the Player Class for Touch Movement
We’ll need a separate float value to hold our horizontal touch input, so add that as a class variable to the Player class.
The TouchMoveHorizontal() Method
We’ll then create a new method that will take in the touch input for movement and assign it to our new variable.
Since the current expected input for horizontal movement is a rounded integer, use Mathf.RoundToInt when reading the value.
Lastly, in the GetPlayerInput() method, we have to overwrite the original _horizInput value.
Since GetPlayerInput() is called every frame and TouchMoveHorizontal() only when an event fires, the _horizInput value is most recent here.
That is why we don’t directly assign _horizInput in the TouchMoveHorizontal() method itself.
We overwrite it after it looks for keyboard input which we know won’t exist when touch is being used and is thus safe to overwrite.
We do make sure that _horizTouchInput is not equal to 0, or we could cause issues for our keyboard build.
What About the Input Manager Class?
If this were a production project, I would move all of the input logic out of the Player class and into the InputManager class.
Then the InputManager class would call public methods in the Player class to pass the necessary values for movement.
Since we have this working and there is nothing new to learn while doing it that hasn’t been covered in previous articles, let’s just leave it here.
Assigning PlayerInput Component’s Events
Now to hook up our Player class’ TouchMoveHorizontal() method to the Input System.
Go to the InputManager gameobject and select its Player Input component.
Expand “Events” and “Character”.
Character is generated from our Input Asset to correspond with the Character Action Map.
As such, it then contains events for every action it has.
In our case that is just the “HoriztonalMove” Action.
Assign the Player gameobject’s Player class and select the TouchMoveHorizontal method.
And we’re done!
Give it a try.
Feel free to build this and deploy it to your Android phone and play around with it.
Most likely we’ll want to adjust the positioning of our buttons and joystick UI to more comfortable positions.
Again, in a production environment, we’d probably want to give users the ability to move these where they like as well.