Handling Input
Unity has two ways to read the keyboard, mouse and gamepad: the older Input Manager (the Input class) and the newer Input System package. This page helps you pick one and get started.
Which one am I using?
The old Input Manager is a light switch wired into the wall: simple, but if you want another switch for the same light you have to rewire it yourself. The new Input System is a universal remote. You define buttons like "Jump" once, then decide which keys or gamepad buttons send that signal. Your code only listens for "Jump" and doesn't care where it came from.
Open Edit > Project Settings > Player > Other Settings > Active Input Handling.
| Setting | What works |
|---|---|
| Input Manager (Old) | Only Input.GetKey etc. |
| Input System Package (New) | Only UnityEngine.InputSystem. Calling Input.GetKey throws an InvalidOperationException. |
| Both | Both work. Handy while learning. |
Input class. If you get the InvalidOperationException from a tutorial's code, set this option to Both.Quick comparison
| Task | Old Input Manager | New Input System |
|---|---|---|
| Space pressed this frame | Input.GetKeyDown(KeyCode.Space) | Keyboard.current.spaceKey.wasPressedThisFrame |
| W held down | Input.GetKey(KeyCode.W) | Keyboard.current.wKey.isPressed |
| Left click this frame | Input.GetMouseButtonDown(0) | Mouse.current.leftButton.wasPressedThisFrame |
| Mouse position (pixels) | Input.mousePosition | Mouse.current.position.ReadValue() |
| Move stick / WASD | Input.GetAxis("Horizontal"), "Vertical" | An Input Action, moveAction.ReadValue<Vector2>() |
Option A: Old Input Manager
Simple and used in most tutorials. See the Input page for all methods.
using UnityEngine;
public class OldInputMover : MonoBehaviour
{
[SerializeField] private float speed = 5f;
void Update()
{
// "Horizontal" = A/D, Left/Right arrows, gamepad left stick X.
// Defined in Project Settings > Input Manager.
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
transform.Translate(new Vector3(x, 0f, z) * speed * Time.deltaTime);
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("Jump!");
}
}
}
Option B: New Input System, reading devices directly
Quickest way to try the new system. Good for prototypes and debug keys.
using UnityEngine;
using UnityEngine.InputSystem;
public class DirectInputExample : MonoBehaviour
{
void Update()
{
// .current is null when no such device is connected, so check it.
if (Keyboard.current != null && Keyboard.current.spaceKey.wasPressedThisFrame)
{
Debug.Log("Jump!");
}
if (Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame)
{
Debug.Log("Clicked at " + Mouse.current.position.ReadValue());
}
}
}
Option C: New Input System with Actions (recommended for real games)
Instead of hard-coding keys, you define actions like "Move" and "Jump" and bind keys and gamepad buttons to them. Players can then use any device, and you can support rebinding.
Unity 6 projects include a default actions asset (InputSystem_Actions) with actions such as "Move", "Look", "Jump" and "Attack" already set up, registered in Project Settings > Input System Package.
using UnityEngine;
using UnityEngine.InputSystem;
public class ActionMover : MonoBehaviour
{
[SerializeField] private float speed = 5f;
private InputAction moveAction;
private InputAction jumpAction;
void Start()
{
// Look up actions from the project-wide actions asset by name.
moveAction = InputSystem.actions.FindAction("Move");
jumpAction = InputSystem.actions.FindAction("Jump");
}
void Update()
{
Vector2 move = moveAction.ReadValue<Vector2>(); // WASD, arrows or left stick
transform.Translate(new Vector3(move.x, 0f, move.y) * speed * Time.deltaTime);
if (jumpAction.WasPressedThisFrame())
{
Debug.Log("Jump!");
}
}
}
What happens at runtime
- At the start of each frame, before
Update, Unity collects all input events from the operating system. - It updates the state of every key, button and axis.
- "Pressed this frame" /
GetKeyDownvalues are true for exactly one frame: the frame the press happened. "Is pressed" /GetKeystays true every frame while held. - Your
Updatecode reads that state.
Common Mistakes
- Reading "down this frame" in FixedUpdate.
FixedUpdatemight not run on the frame of the press, so the press is missed. Read inUpdate, act inFixedUpdate. - Using the old API with only the new system enabled. Causes
InvalidOperationException: You are trying to read Input using the UnityEngine.Input class.... Switch to "Both" or port the code. - Forgetting
using UnityEngine.InputSystem;forKeyboard,MouseandInputAction.
See also
- Input (old Input Manager reference)
- Official Input System package documentation
This page is a simplified, AI-assisted interpretation. For the complete and authoritative reference, see the official Unity documentation.