Unity Input System
Unity offers two input systems:
- Input Manager (legacy) --
Input.GetAxis,Input.GetKeyDown. The default in 2022.3 LTS. Used by every generated script in this project. - Input System package -- the new event-driven API. Available via the
com.unity.inputsystempackage.
Input Manager (legacy)
Axes
The legacy system reads virtual axes defined in
Edit > Project Settings > Input Manager. The defaults include:
| Axis name | Default keys |
|---|---|
Horizontal |
A/D, Arrow Left/Right |
Vertical |
W/S, Arrow Up/Down |
Mouse X |
Mouse delta X |
Mouse Y |
Mouse delta Y |
Jump |
Space |
Fire1 |
Left Ctrl / Mouse 0 |
Fire2 |
Right Alt / Mouse 1 |
Fire3 |
Left Shift / Mouse 2 |
Reading axes
float x = Input.GetAxisRaw("Horizontal"); // -1, 0, +1 (no smoothing)
float y = Input.GetAxis("Vertical"); // smoothed, -1..+1
Vector2 move = new Vector2(x, y);
move = Vector2.ClampMagnitude(move, 1f); // prevent diagonal speed boost
- Use
GetAxisRawfor responsive arcade movement;GetAxisfor smooth camera-style axes. - Always clamp the magnitude of a 2-axis vector -- otherwise diagonal movement is ~1.41x faster than cardinal.
Keys and buttons
if (Input.GetKeyDown(KeyCode.Space)) Jump();
if (Input.GetKey(KeyCode.LeftShift)) Sprint();
if (Input.GetKeyUp(KeyCode.E)) Interact();
if (Input.GetMouseButtonDown(0)) Fire();
if (Input.GetMouseButton(0)) FireContinuous();
| Method | Fires when |
|---|---|
GetKey |
Every frame the key is held |
GetKeyDown |
Only on the frame the key was pressed |
GetKeyUp |
Only on the frame the key was released |
GetMouseButton |
Every frame the button is held |
GetMouseButtonDown |
Only on the frame the button went down |
Mouse position and delta
Vector3 mousePos = Input.mousePosition; // screen-space pixels
float dx = Input.GetAxis("Mouse X"); // smoothed delta
float rawDx = Input.GetAxisRaw("Mouse X");
To lock the cursor for first-person look:
Cursor.lockState = CursorLockMode.Locked; // hide + center
Cursor.visible = false;
Mouse-look recipe (first-person)
private float _pitch;
private void Update()
{
float mx = Input.GetAxisRaw("Mouse X") * sensitivity;
float my = Input.GetAxisRaw("Mouse Y") * sensitivity;
transform.Rotate(Vector3.up * mx);
_pitch = Mathf.Clamp(_pitch - my, -85f, 85f);
cameraTransform.localRotation = Quaternion.Euler(_pitch, 0f, 0f);
}
Mouse-look recipe (third-person orbit)
For a third-person camera we accumulate a yaw and pitch and build a rotation each frame:
_yaw += Input.GetAxis("Mouse X") * sensitivity;
_pitch -= Input.GetAxis("Mouse Y") * sensitivity;
_pitch = Mathf.Clamp(_pitch, -30f, 75f);
Quaternion rotation = Quaternion.Euler(_pitch, _yaw, 0f);
Vector3 position = pivot + rotation * new Vector3(0f, height, -distance);
The ThirdPersonCamera.cs generator follows exactly this pattern.
Input System package (new)
When the project has the Input System package active, the legacy Input
class will throw or return zeros unless Project Settings > Player > Active Input Handling = Both.
The new API is event-based:
[SerializeField] private InputActionAsset actions;
private InputAction _moveAction;
private void OnEnable()
{
_moveAction = actions.FindAction("Move");
_moveAction.performed += OnMove;
_moveAction.Enable();
}
private void OnMove(InputAction.CallbackContext ctx) => _moveInput = ctx.ReadValue<Vector2>();
private void OnDisable() => _moveAction.Disable();
For the generated project we keep Active Input Handling on Both so the
legacy Input calls in the generated scripts keep working.
Touch and mobile
For mobile, read Input.touches (legacy) or the new Input System's
Pointer/Touchscreen:
foreach (Touch t in Input.touches)
{
if (t.phase == TouchPhase.Began) HandleTap(t.position);
}
The generated scripts are desktop-first; you would add a virtual joystick overlay for mobile ports.
Common pitfalls
- Reading
InputinFixedUpdate-- the input system updates once per frame, butFixedUpdatemay run 0..N times per frame, so you will drop or duplicate inputs. - Using
Input.GetAxisfor physics forces -- the smoothed value can cause floaty controls. PreferGetAxisRawand apply your own smoothing. - Forgetting to lock the cursor in an FPS leads to the camera spinning when the cursor leaves the game window.