# 1. Package Setup and Action Foundations Part of [[Input System]]. **Target:** Unity 6000.5+ / Input System 1.20.x. Next: [[2. Control Schemes Devices and Consumption Patterns]]. Lighter parallel: [[Unity New Input System Upgrade Tutorial]]. > [!warning] Verification status > Installation steps, action types, and composite types were checked against Input System **1.20.1** docs. Script snippets were **not** compiled in Unity. ## 1.1 Install and pick a backend Docs: [Install the Input System package](https://docs.unity3d.com/Packages/[email protected]/manual/Installation.html). Unity Manual for 6000.5 lists package **1.20.0** as released: [Input System package page](https://docs.unity3d.com/Manual/com.unity.inputsystem.html). 1. **Window > Package Manager > Unity Registry**, select **Input System**, **Install** (skip if the template already included it). 2. When prompted to enable the new backends, choose **Yes**. The Editor restarts. 3. Or set it manually: **Edit > Project Settings > Player > Other Settings > Active Input Handling**: - **Input System Package (New)** — defines `ENABLE_INPUT_SYSTEM`. Prefer this for new work. - **Input Manager (Old)** — `ENABLE_LEGACY_INPUT_MANAGER`. Avoid for new projects. - **Both** — both defines. Useful while migrating `Input.GetAxis` code; remove **Both** once done so you do not accidentally keep dual paths forever. Import the package **Samples** (especially **Rebinding UI** and **Simple Demo**) from the same Package Manager page when you want reference scenes. ## 1.2 Create an Input Actions asset An **Input Action Asset** (`.inputactions`) stores maps, actions, bindings, and control schemes as JSON. 1. Project window: **Create > Input Actions**. Name it `PlayerInputActions`. 2. Double-click to open the **Input Actions Editor** (same editor appears under **Edit > Project Settings > Input System Package** for project-wide actions). 3. Save the asset (**Ctrl+S** / **Cmd+S**) whenever you change bindings — unsaved assets silently fail in Play Mode. You usually want **one** gameplay asset plus the default **UI** map (either in the same asset or project-wide). Multiple assets are fine for tools vs runtime, but player/UI split-across-three-assets gets hard to reason about. ## 1.3 Action maps An **action map** is a situational group. Typical set: | Map | When it is enabled | |---|---| | `Player` | Locomotion, look, jump, attack, interact | | `UI` | Navigate, Submit, Cancel, Point, Click, Scroll | | `Vehicle` | Only while driving ([[Car Controller]]) | | `Menus` | Pause / options when gameplay map is disabled | Enable **exactly the maps that should receive input**. A common bug is leaving `Player` enabled under a full-screen pause menu so Jump still fires. Swap maps explicitly: ```csharp using UnityEngine; using UnityEngine.InputSystem; public sealed class ActionMapSwitcher : MonoBehaviour { [SerializeField] InputActionAsset actions; InputActionMap _player; InputActionMap _ui; void Awake() { _player = actions.FindActionMap("Player", throwIfNotFound: true); _ui = actions.FindActionMap("UI", throwIfNotFound: true); } public void EnterGameplay() { _ui.Disable(); _player.Enable(); } public void EnterMenus() { _player.Disable(); _ui.Enable(); } void OnDestroy() { _player?.Disable(); _ui?.Disable(); } } ``` ## 1.4 Action types: Button, Value, PassThrough Docs: [Action types reference](https://docs.unity3d.com/Packages/[email protected]/manual/action-type-reference.html). | Type | Use when | Phases / conflict resolution | |---|---|---| | **Button** | Discrete presses (Jump, Interact, Fire) | Yes — started / performed / canceled, and "most actuated wins" | | **Value** | Continuous axes (Move `Vector2`, Look `Vector2`, Trigger `float`) | Yes — same phase + conflict model | | **PassThrough** | Raw fan-in from many controls (multi-pointer UI, tracked XR poses feeding one action) | **No** phase tracking and **no** conflict resolution — every bound control can callback | Rule of thumb: gameplay Move/Look/Jump → **Value** or **Button**. XR tracked position/orientation shared across controllers for UI → **PassThrough** (required by tracked UI docs). ## 1.5 Bindings A **binding** maps a control path to an action, optionally scoped to a control scheme. Examples of paths: - `<Keyboard>/space` - `<Gamepad>/buttonSouth` - `<Mouse>/delta` - `<Gamepad>/leftStick` - `<XRController>{LeftHand}/trigger` *(device-dependent; verify on your OpenXR profile)* In the Binding Properties panel you assign **Use in control scheme** checkboxes. For composites, assign schemes on the **part** bindings (Up/Down/Left/Right), not only the composite root — see [Group bindings to control schemes](https://docs.unity3d.com/Packages/[email protected]/manual/group-binding-to-control-scheme.html). ## 1.6 Composites Docs: [Composite Bindings](https://docs.unity3d.com/Packages/[email protected]/manual/composite-bindings.html). Composites synthesize a higher-dimensional value from several button-like controls: | Composite | Output | Typical use | |---|---|---| | **1D Axis** (Positive/Negative) | `float` | Accelerate / brake, or scroll alternatives | | **2D Vector** (Up/Down/Left/Right) | `Vector2` | WASD / arrows Move | | **3D Vector** | `Vector3` | Rare; free-fly editors | | **One Modifier** | Same as binding part | Shift+1 style chords | | **Two Modifiers** | Same as binding part | Ctrl+Shift+… | For Move: Action Type **Value**, Control Type **Vector2**, then **Add Up/Down/Left/Right Composite**. Mode **Digital** (normalized cardinal) vs analog-style behavior is a composite property — pick Digital for keyboard WASD unless you want diagonal magnitude > 1 quirks addressed another way (often a **Normalize** processor on the action). ## 1.7 Processors Docs: [Processors](https://docs.unity3d.com/Packages/[email protected]/manual/Processors.html). Processors transform values **after** the control is read. Common built-ins: - **Normalize** / **Normalize Vector 2** — keep stick/WASD magnitude sane - **Stick Deadzone** — ignore tiny stick noise - **Scale** / **Scale Vector 2** — mouse look sensitivity - **Invert** / **Invert Vector 2** — invert Y look - **Clamp** — limit triggers or axes Apply on the **binding** (per-device: mouse Look scaled differently than stick Look) or on the **action** (global). Prefer binding-level Scale for mouse delta so gamepad look stays untouched. ## 1.8 Interactions Docs: [Interactions](https://docs.unity3d.com/Packages/[email protected]/manual/Interactions.html), [Predefined interactions](https://docs.unity3d.com/Packages/[email protected]/manual/predefined-interactions.html). Interactions decide **when** an action reports `performed` relative to actuation: - **Press** — fire on press (Down / Release / Instant variants depending on settings) - **Hold** — performed after a duration (interact / charge) - **Tap** — short press window - **Slow Tap** - **Multi Tap** Put a **Hold** interaction on Interact when you want "hold to pick up" without polling timers in gameplay code. Put Multi Tap on a debug action, not on Jump. ## 1.9 Reading actions from code (preview) Three styles you will formalize in part 2: ```csharp using UnityEngine; using UnityEngine.InputSystem; public sealed class PollMoveExample : MonoBehaviour { [SerializeField] InputActionReference move; void OnEnable() => move.action.Enable(); void OnDisable() => move.action.Disable(); void Update() { Vector2 v = move.action.ReadValue<Vector2>(); // apply to character… _ = v; } } ``` ```csharp void OnEnable() { move.action.performed += OnMove; move.action.canceled += OnMove; move.action.Enable(); } void OnDisable() { move.action.performed -= OnMove; move.action.canceled -= OnMove; move.action.Disable(); } void OnMove(InputAction.CallbackContext ctx) { Vector2 v = ctx.ReadValue<Vector2>(); _ = v; } ``` Polling `ReadValue` every `Update` is fine for Move/Look. Use callbacks for edge-triggered Button actions (Jump started/performed) so you do not miss a press between frames when your script execution order is awkward. ## 1.10 Suggested Player map (you will flesh this out in part 5) | Action | Type | Control Type | Starting bindings | |---|---|---|---| | Move | Value | Vector2 | 2D Vector WASD + arrows; `<Gamepad>/leftStick` | | Look | Value | Vector2 | `<Mouse>/delta` (Scale); `<Gamepad>/rightStick` | | Jump | Button | Button | `<Keyboard>/space`; `<Gamepad>/buttonSouth` | | Interact | Button | Button | `<Keyboard>/e`; `<Gamepad>/buttonWest` (+ optional Hold) | Add schemes **Keyboard&Mouse** and **Gamepad**, tick them on the appropriate bindings, save, then continue to part 2.