Managing user interaction with the Unity’s input system

It’s hard to believe, but Unity is now 20 years old. It was actually announced at Apple’s 2005 WWDC and since then, it has become a juggernaut in the game industry. When Unity was developed, it was focused on the desktop. Later, it gained support for the web browser, and soon, consoles.

While Unity has expanded across platforms, hardware types and control schemes, it used the same input system. This system was a little clunky and prone to errors. That said, it was pretty use. After years of use, Unity finally updated the input system with the goal of providing ease of use along with developer flexibility.

Note: This tutorial is part of a collection that teaches Unity development from the ground up. You can read the entire series over here. This series is free and does not require any account creation. All assets are provided. If you find it useful, feel free to buy me a coffee.

This system isn’t as straightforward as the legacy input system. That said, you’ll put it to use in your game.

Understanding Unity’s Input System

In the old days, when the legacy input system was king, you needed to opt-into the new input system. Now, every Unity 6 project is configured to use it. It’s actually straightforward to get started with it, but it does require some boilerplate code.

Note: You’ll implement the system in code in this chapter, but this is not meant to be a deep dive on the subject. There are some resources noted at the end of this tutorial. Also note, there is a bit of tinkering required for updating existing projects to use the new Input System. That is beyond the scope of this tutorial.

With your project open, take a look at the root level of y our Assets folder. You’ll see a file called InputSystem.inputsettings. Double-click the file. You’ll see the Project Settings appear. This is where you configure various aspects of your control scheme, such as dead zones and button presses.

This shows the input settings in the project settings dialog.

You don’t need to configure these options, so close the dialog. You’ll also notice the InputSysyem_Action has a disclosure triangle next to it. Expand it, and you’ll see all the configured actions out of the box.

This shows the list of actions in the input system actions.

You’re going to make the player more, so double-click the Move action. This opens a dialog of actions.

This shows the expanded move action with all the key bindings.

When you expand the Move action, you can configure all the default keys at the start of the game. You can also determine how they behave. For now, you’ll use the default values.

Setting up the input system

Now to actually implement the control scheme. In the Project Browser, double-click the PlayerController script to launch the editor. To get started, delete all the existing variables from the previous tutorial. Your script should now look like a new script.

First, you need to add a using statement to access the input system. Update the using statements at the top of the script to the following:

using UnityEngine;
using UnityEngine.InputSystem;

Your file should look like the following:

This shows the update using statements.

Now, you need to access the input system actions in code. For this, you must generate a class file. Return to Unity. Select the InputSystem_Actions in the Project window, and in the Inspector, check the Generate C# Class file. Then click the Apply button.

This shows the generate C# class dialog.

Return to Visual Studio. Add the following variables underneath the class definition.

public class PlayerController : MonoBehaviour
{
  private InputSystem_Actions playerActions;
  private InputAction move;

The InputSystem_Actions refer to all the current actions available to the player. You’re using the default actions, but these will also refer to any custom actions that you may create. The InputAction refers to specific action. In this case, you are referring to the move action.

Now, you need to create a new instance of your actions object. Add the following method underneath your variables:

void Awake()
{
  playerActions = new InputSystem_Actions();
  move = playerActions.Player.Move;
}

Awake() is called when the MonoBehaviour object is created. This is only called once. It makes for a good place to create your actions. First, you create actions object and then you get the move action. Add the following:

void OnEnable()
{
  move.Enable();
}

void OnDisable()
{
  move.Disable();
}

This is your basic boilerplate code. When the SpaceMarine is enabled, he should receive walk actions. When he is disabled, he should not. Now for the actual magic: the movement code.

Moving the marine

It’s time to move around. You have the action configured, you just need to calculate the marine placement.

Underneath the open curly brace, add the following variable:

[SerializeField]
private float moveSpeed = 50.0f;

moveSpeed is a variable that determines how fast the hero moves around in the arena. You set it to a default value of 50 that you can change later in Unity’s interface.

Now, to write the actual moving code. In Update(), add the following:

Vector3 pos = transform.position;

This bit of code simply gets the current position of the current GameObject — in this case, the space mmarine,since that is what this script is attached to — and stores it in a variable named pos. In Unity, a Vector3 encapsulates the x, y and z of a GameObject, i.e., the object’s point in 3D space.

Add the following after the previous line:

Vector2 moveDirection = move.ReadValue<Vector2>();

This gets the value of the movement from the input. It reads the value as a Vector2 object. This encapsulates the x and y coordinates of the controller movement. Add the following underneath the last line of code:

pos.x += moveSpeed * moveDirection.x * Time.deltaTime;
pos.z += moveSpeed * moveDirection.y * Time.deltaTime;

When you move the object, it’ll only be on z- and x-axes because y represents up and down. Because there are two different input sources (x for left and right, and y for up and down), you need to calculate values for each axis separately.

The value returned is either 1 or -1, with 1 indicating that a positive button in the Input Manager is being pressed. According to the settings you saw defined earlier, this is either the right arrow or d keys. Similarly, a value of -1 indicates that a negative button is being pressed, meaning it was either the left arrow or the a key.

This shows the keys along a number line. A represents -1 where D represents 1.

Whatever the returned value may be, it’s then multiplied by the moveSpeed and added to the current x position of the GameObject, effectively moving it in the desired direction.

The same thing happens with y coordinate except it retrieves a value from the vertical component of the Input Manager (indicating the s, down, w or up keys), multiplies this (1 or -1) value by the moveSpeed and adds it to the z position of the GameObject.

So what’s with Time.deltaTime? That value indicates how much time has passed since the last Update(). Remember, Update() is called with every frame, so that time difference must be considered, or the space marine would move too fast to be seen.

TLDR Time.deltaTime ensures movement is in sync with the frame rate.

Note: By default, Unity considers one point to be equal to one meter, but you don’t have to follow this logic. For instance, you may be making a game about planets, and that scale would be far too small. For the purposes of simplicity in this book, we have sized our models to follow Unity’s default of one point per meter.

Now that you’ve altered the location, you have to apply it to the SpaceMarine GameObject. Add the following after the previous line:

transform.position = pos;

This updates the SpaceMarine GameObject’s position with the new position. Save the script and switch back to Unity.

Playing the game

While your main camera is a mess, you can still actually play the game in the Scene view. Position the view so that you can see the entire arena.

This shows the zoomed out arena with the marine in the center.

At the center top of the editor, you’ll see the game controls. Press the play button.

This shows the game play button.

It will take a moment, but your game will play. Now, move your marine using the WASD keys. The play button will turn into a stop button. Press it when you are done playing the game. It took a bit of time, but now you have some interactivity. Granted, the fun is just starting.

Where to go from here

Unity’s new input system is kind of a beast. It’s very complex, but it gives you a lot of flexibility. That said, it’s going to take some time to get used to it.

Here’s a great tutorial by gamedevbeginner.com that explores some of the real nitty-gritty. That said, you’ll be working with it again once you add shooting to the mix.

Unfortunately, your main camera is a bit of a disaster. It’s pointed at a random point in the arena. It is better positioned behind the marine, and it should follow the marine around the arena. You’ll do this in the next tutorial.


Discover more from Jezner Blog

Subscribe to get the latest posts sent to your email.

By Brian Moakley

Brian Moakley is a writer and editor who lives amongst the quiet hills in New England. When not reading tales of high adventure, he is often telling such stories to all who will listen.

Related Post

Leave a Reply