How to Swap Action Maps
Why do we need to swap Action Maps?
Sometimes, your video games might have multiple Action Maps to control different characters and objects. For example, you might have a Player Action Map to control your character. However, when your character hops into a car, you would need another Action Map to drive it around. In a more complex situation, you might even have more Action Maps, and this is when we need functionality to switch between them.
How do we do that?
Let’s create a simple Action Map switching functionality for a Player and Vehicle Action Map. First, we need to set up a ‘switching’ action for each Action Map triggered by the T key press.
Next, in the Player script, I’m going to declare a variable to check if we’re currently in the driving state and register the ‘SwitchToDriving’ and ‘SwitchToPlayer’ actions to a ‘switching’ function:
private bool _isDriving = false;
void Start(){
_input.Player.SwitchToDriving.performed += SwitchActionMap_performed;
_input.Vehicle.SwitchToPlayer.performed += SwitchActionMap_performed;
}
private void SwitchActionMap_performed(InputAction.CallbackContext context)
{
_isDriving = !_isDriving;
}
After that, we need to check if we’re currently in the driving state. If we are, we disable the Player Action Map and enable the Vehicle Action Map, and vice versa.
void Update()
{
if (_isDriving)
{
_input.Player.Disable();
_input.Vehicle.Enable();
} else
{
_input.Player.Enable();
_input.Vehicle.Disable();
}
Drive();
}
private void Drive()
{
var drive = _input.Vehicle.Drive.ReadValue<Vector2>();
transform.Translate(new Vector3(drive.x, 0, drive.y) * Time.deltaTime * _driveSpeed);
}
Here’s the full code:
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour
{
private PlayerInputActions _input;
private float _rotSpeed = 200f;
private float _driveSpeed = 10f;
private bool _isDriving = false;
[SerializeField] private MeshRenderer _render;
private byte _r;
private byte _b;
private byte _g;
private byte _a;
private void Start()
{
_input = new PlayerInputActions();
_input.Player.Enable();
_input.Player.ChangeColor.performed += ChangeColor_performed;
_input.Player.SwitchToDriving.performed += SwitchActionMap_performed;
_input.Vehicle.SwitchToPlayer.performed += SwitchActionMap_performed;
}
void Update()
{
if (_isDriving)
{
_input.Player.Disable();
_input.Vehicle.Enable();
} else
{
_input.Player.Enable();
_input.Vehicle.Disable();
}
Rotate();
Drive();
}
private void SwitchActionMap_performed(InputAction.CallbackContext context)
{
_isDriving = !_isDriving;
}
private void ChangeColor_performed(InputAction.CallbackContext context)
{
_r = System.Convert.ToByte(Random.Range(0, 256));
_b = System.Convert.ToByte(Random.Range(0, 256));
_g = System.Convert.ToByte(Random.Range(0, 256));
_a = System.Convert.ToByte(Random.Range(0, 256));
_render.material.color = new Color32(_r, _b, _g, _a);
}
private void Rotate()
{
var rotate = _input.Player.Rotate.ReadValue<float>();
transform.Rotate(0f, rotate * Time.deltaTime * _rotSpeed, 0f);
}
private void Drive()
{
var drive = _input.Vehicle.Drive.ReadValue<Vector2>();
transform.Translate(new Vector3(drive.x, 0, drive.y) * Time.deltaTime * _driveSpeed);
}
}
The Player Action Map allows us to rotate and change color, while the Vehicle one lets us move around. We can switch between them using the T key. And here’s the result: