Really basic coding tutorial for the new Unity Input System

Really basic coding tutorial for the new Unity Input System

I was really curious about Unity’s new input system. Abstracting player inputs from all different platforms and devices into a single actions set is really smart – I mean, I’ve been working like that for years thanks to the Rewired plugin, it’s great. So it’s exciting that Unity now has a native way to achieve the same. But the big difference is that while Rewired makes it stupidly easy, the new Input system (seemingly) does not. It CAN, but Unity’s documentation is bad at explaining this, and frankly so are most of the tutorials I’ve watched or read, which is why I’m writing this quick guide.

For the purpose of this guide I’m going to assume you have some basic knowledge of the input system, like how to install it and create an Input Action asset. If not, this is one of the nicer tutorials I’ve seen so far to get up to speed (you’d only need to watch the first 6 minutes).

See, you used to be able to do this:

void Update() {
    if (Input.GetKeyDown(Keycode.E)) {
        // Interact with object
    }
}

For comparison, this is Rewired (given that you’ve already created input actions):

void Awake() {
    player = Rewired.ReInput.players.GetPlayer(playerId);
}

void Update() {
    if (player.GetButtonDown("Interact")) {
        // Interact with object
    }
}

Now, I’ve watched about a dozen tutorials on Unity’s new input system, and they all explain it in a different way, but this seems to be the preferred new method (given that you created an actions asset AND are using Unity’s PlayerInput component on the same object as the one with this script):

public void OnInteract(InputAction.CallbackContext context) {
    if (context.performed) {
        // Interact with object?
    }
}

void Update() {
    // ???
}

This obfuscates a lot of what the Input System is doing in the background, but it works. However, this is not how I code. It doesn’t make sense to me to have one function that does a thing in isolation, I want to be able to poll a button press whenever I need it. And attaching a PlayerInput component to each object seems like overkill too.

There is another way to do this, and it involves accessing the actions asset directly through code. Unity added a useful affordance for this, but the way I see most people explain this makes it sound hugely complicated in a way that I almost wanted to stop using the Input System. I’ll spare you the explanation, and instead tell you there’s an easier way.

The One Weird Trick

In this example mine I’ve already created an Input Actions asset in my project, called PlayerInputActions, and inside I’ve mapped the E key to the “Interact” action.

Step 1: Find your actions asset in the project hierarchy. Click on it, and in the Inspector, check ”Generate C# class” and hit Apply.

Step 2: Open any script where you want to perform an action, and add this code:

PlayerInputActions Input;

void Awake() {
    Input = new PlayerInputActions();
    Input.Enable();
}

void Update() {
    if (Input.Player.Interact.WasPressedThisFrame()) {
        // Interact with object
    }
}

This is the most straightforward way I’ve found to get the same functionality as I had before.

There seems to be half a dozen ways to call on this new input system, and I have no idea which one is the most failsafe and efficient, so if you know a better way, please let me know. The code above at least gives me the clean, easy implementation that I was used to.

Bonus

If you’re prototyping and you can’t be arsed to even create/use an action asset yet, you can also do this:

using UnityEngine.InputSystem;

void Update() {
    if (Keyboard.current.eKey.wasPressedThisFrame) {
        // Interact with object
    }
}

This is literally how it used to work, but of course it bypasses the benefits of the new input system entirely. But still, useful in some cases. You can also pass it gamepad buttons, etc.

Hope that helped!

Leave a Reply