Unity Dev: Multiple Action Maps (New Input System)
In yesterday’s article, we added some UI to direct the player to press the “Enter” key or the Start button on a gamepad to restart the game when they’ve died. Wait though… our Input Actions are tied to our Player object and when we die, we destroy it! So how do we continue providing input?
Refactoring OnMove() and OnFire()
Let’s begin by making an empty Game Object called “Input_Manager”. Add a coordinating C# script “InputManager” and attach it to the object. Create a new Player Input component on the object as well and set its Behaviour to “Invoke Unity Events”.
The general idea here, is that we’re going to add another Action Map dedicated to controls that can be used when the Player is dead. To do this, we’re going to shift the responsibility of knowing which Action Map to use over to a persistent Game Object. You can go ahead and delete the Player Input component on your Player object as well.
Let’s define our new Action Map. In your InputActions folder, double-click you “Controls” item to open the Input Actions editor and add a new Action Map called “Death Menu”.
Now, here’s the really cool thing about this refactoring of our control systems. We don’t even need to modify our code to keep our Movement and Firing mechanisms working. Expand the Events > Player in the Player Input component on your Input_Manager, use the + button under “Move” and “Fire” to create new events. Drag your Player object into these, and select the
OnFire from the Player list.
Run your game and everything should work exactly the way it did before. This is great, because we obviously don’t want our existing functionality breaking in an attempt to add new functionality.
Switching Action Maps
Now, when our player dies, we show a screen saying “Game Over” and, more importantly “Enter/Start to Restart”.
We’ve already got our “Death Menu” Action Map for just such an occasion. There’s a couple steps involved in making this happen.
- Load up a reference to our InputManager in Player.cs (use
GetComponent<>()) and null check!
- Load a reference to our Player Input component on our InputManager in InputManager.cs with
GetComponent<>(). Null check null check null check.
- Use the PlayerInput component to switch Action Maps when the player dies.
- Make a
void OnRestart(InputAction.CallbackContext context)inside of our UIManager.cs. This is where we’ll run our scripts to restart the game.
- Setup the Player Input component on the Input_Manager object to use the Restart function from UIManager in Events > Death Menu.
Step 3 is the one we’re mostly unfamiliar with in this case, so let’s have a look at that.
We’ve created another
void OnPlayerDeath() for the Player.cs to call from our InputManager. We’ve referenced our Player Input component inside of
_playerInput and proceed to set the
currentActionMap by using the
FindActionMap() method which accepts a string. In this case, the name of our new Action Map is “Death Menu”.
After establishing your reference to the InputManager in your Player script, you can call its
OnPlayerDeath() function when the player dies.
Play your game. When you run out of lives, you’ll see your GAME OVER screen, but behind the scenes, your InputManager will switch over to using the “Death Menu” Action Map, allowing the player to restart the game and go again!