# Unity Input System Unity offers two input systems: 1. **Input Manager (legacy)** -- `Input.GetAxis`, `Input.GetKeyDown`. The default in 2022.3 LTS. Used by every generated script in this project. 2. **Input System package** -- the new event-driven API. Available via the `com.unity.inputsystem` package. ## 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 ```csharp 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 `GetAxisRaw` for responsive arcade movement; `GetAxis` for 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 ```csharp 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 ```csharp 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: ```csharp Cursor.lockState = CursorLockMode.Locked; // hide + center Cursor.visible = false; ``` ## Mouse-look recipe (first-person) ```csharp 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: ```csharp _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: ```csharp [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(); 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`: ```csharp 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 `Input` in `FixedUpdate` -- the input system updates once per frame, but `FixedUpdate` may run 0..N times per frame, so you will drop or duplicate inputs. * Using `Input.GetAxis` for physics forces -- the smoothed value can cause floaty controls. Prefer `GetAxisRaw` and apply your own smoothing. * Forgetting to lock the cursor in an FPS leads to the camera spinning when the cursor leaves the game window.