Input Systems¶
New Input System (Recommended)¶
The Input System package (com.unity.inputsystem 1.7+) is the modern standard for all new Unity projects. It provides an event-driven model, unified device support, and built-in rebinding.
Input Actions Asset¶
Create an .inputactions asset to define all input bindings:
- Right-click in Project window: Create > Input Actions
- Define Action Maps (Player, UI, Vehicle)
- Define Actions within each map (Move, Jump, Fire, Look)
- Add Bindings to each action (keyboard, gamepad, touch)
Action Maps¶
Organize input by context: - Player: movement, jumping, attacking, interacting - UI: navigation, submit, cancel, scroll - Vehicle: steering, acceleration, braking - Menu: back, tab switching
Switch maps at runtime:
Composite Bindings¶
Use composites for multi-key inputs: - 2D Vector (WASD): combines W/A/S/D into a Vector2 - 1D Axis: combines two keys into a float (-1 to 1) - Button With One Modifier: Ctrl+S, Shift+Click
Composites are more efficient than polling individual keys.
PlayerInput Component¶
The simplest way to receive input. Add the PlayerInput component and choose a behavior mode:
- Send Messages: Calls
OnMove(InputValue),OnJump(InputValue)methods on the same GameObject - Invoke Unity Events: Wire actions to UnityEvents in the inspector
- Invoke C# Events: Subscribe in code
Direct C# API¶
For full control:
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour
{
private PlayerInputActions _input;
private void Awake()
{
_input = new PlayerInputActions();
}
private void OnEnable()
{
_input.Player.Enable();
_input.Player.Jump.performed += OnJump;
_input.Player.Fire.performed += OnFire;
}
private void OnDisable()
{
_input.Player.Jump.performed -= OnJump;
_input.Player.Fire.performed -= OnFire;
_input.Player.Disable();
}
private void Update()
{
Vector2 moveInput = _input.Player.Move.ReadValue<Vector2>();
Move(moveInput);
}
private void OnJump(InputAction.CallbackContext ctx)
{
Jump();
}
private void OnFire(InputAction.CallbackContext ctx)
{
Fire();
}
}
Callback Phases¶
Each action has three phases: - started: Input begins (key pressed, stick moved off center) - performed: Input reaches its threshold (button fully pressed, hold time met) - canceled: Input ends (key released, stick returns to center)
Runtime Rebinding¶
public async void StartRebinding(InputAction action)
{
action.Disable();
var operation = action.PerformInteractiveRebinding()
.WithControlsExcluding("Mouse/position")
.OnComplete(op =>
{
op.Dispose();
action.Enable();
SaveBindings();
})
.Start();
}
Local Multiplayer¶
Use PlayerInputManager for split-screen or shared-screen multiplayer:
- Set Join Behavior (press button to join, auto-join on connect)
- Assign different control schemes per player
- PlayerInput components are auto-instantiated per player
Legacy Input Manager¶
The old Input.GetKey/Input.GetAxis API. Use only for:
- Maintaining legacy projects that cannot migrate
- Ultra-quick throwaway prototypes
// Legacy - avoid for new projects
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
bool jump = Input.GetButtonDown("Jump");
Why Migrate¶
- No runtime rebinding support
- No composite bindings
- Poor device abstraction (gamepad support is limited)
- Polling-based (checks every frame even when nothing changes)
- No action map switching