# 4. UI Input and XR Input Part of [[Input System]]. Previous: [[3. Runtime Rebinding]]. Next: [[5. Worked Example Remappable Player]]. Desktop UI companions: [[UI Toolkit and Diegetic UI]]. VR UI: [[8.UI Toolkit for VR]]. Quest device/hands detail lives in [[Meta Quest 2]] and [[6.Quest 2 Input Hands and Passthrough]] — this part only shows how those actions sit on the Input System. > [!warning] Verification status > `InputSystemUIInputModule`, tracked PassThrough requirement, and `TrackedDeviceRaycaster` come from Input System **1.20.1** UI docs. XR Interaction Toolkit `XRUIInputModule` notes summarize XRI package docs and were **not** validated against a specific XRI version in-editor. Quest binding paths are **unverified** device strings — prefer the maps from your Quest tutorial set. Scripts were **not** compiled in Unity. ## 4.1 EventSystem + Input System UI Input Module Docs: [Introduction to the UI Input Module](https://docs.unity3d.com/Packages/[email protected]/manual/introduction-ui-input-module.html), [Supported input types](https://docs.unity3d.com/Packages/[email protected]/manual/supported-ui-input-types.html). For **uGUI** (and UI Toolkit panels that still go through EventSystem): 1. Scene needs an **Event System**. 2. Remove **Standalone Input Module** (legacy). 3. Add **Input System UI Input Module** (`InputSystemUIInputModule`). 4. Point its actions at your asset's **UI** map (or leave project-wide defaults). Default UI actions usually include Navigate, Submit, Cancel, Point, Click, Scroll Wheel, Middle/Right Click, and tracked device Pose fields. When a component instance exists in the scene, **its** assignments win over project-wide UI settings, and it enables the UI map alongside the module's default map. ```csharp using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.InputSystem.UI; public static class UiInputBootstrap { [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] static void EnsureModule() { var es = EventSystem.current; if (es == null) return; if (es.GetComponent<InputSystemUIInputModule>() != null) return; // Illustrative only — prefer configuring in the Editor. var legacy = es.GetComponent<StandaloneInputModule>(); if (legacy != null) Object.Destroy(legacy); es.gameObject.AddComponent<InputSystemUIInputModule>(); } } ``` ## 4.2 UI Toolkit note On modern Unity 6, UI Toolkit can receive pointer events without always needing the same uGUI path you used in 2021-era projects, but **gamepad/keyboard navigation** and shared pause menus still commonly use EventSystem + `InputSystemUIInputModule`. Diegetic world-space panels are covered in [[UI Toolkit and Diegetic UI]]; VR world-space Toolkit panels are in [[8.UI Toolkit for VR]]. Do not run two competing input modules on one EventSystem. ## 4.3 Pausing gameplay while UI is open ```csharp using UnityEngine; using UnityEngine.InputSystem; public sealed class PauseInputGate : MonoBehaviour { [SerializeField] InputActionAsset actions; InputActionMap _player; InputActionMap _ui; void Awake() { _player = actions.FindActionMap("Player"); _ui = actions.FindActionMap("UI"); } public void SetPaused(bool paused) { if (paused) { _player.Disable(); _ui.Enable(); Cursor.lockState = CursorLockMode.None; Cursor.visible = true; } else { _ui.Disable(); _player.Enable(); Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; } } } ``` During **rebinding**, keep UI Submit/Cancel enabled (or a dedicated Menus map) so Esc can cancel; disable only the Player actions being rebound. ## 4.4 Tracked-device (XR) UI with the Input System module Docs: [Tracked input UI support](https://docs.unity3d.com/Packages/[email protected]/manual/supported-ui-input-types-tracked.html). Tracked controllers feed **world pose** into UI via: - Actions for `trackedDevicePosition` and `trackedDeviceOrientation` — type **PassThrough** (mandatory so both hands relay). - **`TrackedDeviceRaycaster`** on the Canvas GameObject (can sit beside `GraphicRaycaster`). - Ordinary click actions (`leftClick` / Click) for press. Without PassThrough, conflict resolution will drop one controller's stream and UI rays feel "possessed" by a single hand. ## 4.5 XR Interaction Toolkit path (Quest projects) For Meta Quest work you already document under [[Meta Quest 2]], XRI expects **`XRUIInputModule`** on the EventSystem and tells you to **remove** Standalone / Input System UI Input Module so only one module runs. Prefer the **XRI Default Input Actions** / **XRI Default XR UI Input Module** preset from XRI Starter Assets when available. Relationship: | Stack | UI module | When | |---|---|---| | Desktop / non-XRI | `InputSystemUIInputModule` | Flat games, editor tools, non-XR UI Toolkit | | XRI / Quest interactors | `XRUIInputModule` | Near-Far / Ray / Poke UI | | Input System tracked rays without XRI | `InputSystemUIInputModule` + `TrackedDeviceRaycaster` | Custom XR without XRI | Do **not** duplicate the hands, passthrough, or OpenXR setup here — use [[6.Quest 2 Input Hands and Passthrough]]. From this tutorial you only need: 1. Separate **Player** vs **UI** vs **XRI** maps (or schemes). 2. PassThrough on tracked pose actions. 3. One EventSystem input module appropriate to the stack. 4. Awareness that Quest builds for Marshall's sideload fleet target **Unity 6.3 LTS (6000.3.27f2+)**, while this general Input System deep dive stays on **6000.5+**. ## 4.6 Minimal XR controller action sketch (desktop mock or custom XR) ```csharp using UnityEngine; using UnityEngine.InputSystem; /// <summary> /// Reads a PassThrough Vector3 pose action. Bindings come from your XR device layout. /// Prefer XRI's action assets in Quest projects instead of hand-rolling this. /// </summary> public sealed class XrPoseDebug : MonoBehaviour { [SerializeField] InputActionReference trackedPosition; // PassThrough, Vector3 [SerializeField] InputActionReference trackedRotation; // PassThrough, Quaternion void OnEnable() { trackedPosition.action.Enable(); trackedRotation.action.Enable(); trackedPosition.action.performed += OnPos; } void OnDisable() { trackedPosition.action.performed -= OnPos; trackedPosition.action.Disable(); trackedRotation.action.Disable(); } void OnPos(InputAction.CallbackContext ctx) { Vector3 p = ctx.ReadValue<Vector3>(); Debug.Log(quot;Tracked pos from {ctx.control.device.name}: {p}"); } } ``` ## 4.7 Cross-link checklist for VR notes When you extend Quest content, link back here for asset/rebinding theory, and keep device-specific steps in: - [[Meta Quest 2]] — HMD project baseline - [[6.Quest 2 Input Hands and Passthrough]] — hands / controllers / passthrough - [[8.UI Toolkit for VR]] — world-space Toolkit Next: build the remappable desktop player that ties parts 1–3 together.