UI in VR is not a screen the user sees in front of them. It's objects in space that they interact with using hands or beams. Our engineers with 8+ years of experience in game development handle this turnkey: from prototype to final deployment. The familiar Canvas in Screen Space won't work. World Space Canvas is the starting point, but that's where the challenges begin.
Common mistake: take a 2D game UI, switch Canvas to World Space, place it in front of the player — and get a panel that's either too close (uncomfortable to read in VR at 30 cm), too far, or unresponsive to controllers. We'll evaluate your project — contact us for a consultation.
Why Standard Canvas Screen Space Doesn't Work for VR
Screen Space Canvas is tied to the screen. In VR, it doesn't account for depth — text and buttons overlay the scene, causing a conflict between accommodation and convergence. This leads to rapid fatigue and dizziness. World Space Canvas places UI in real-world coordinates: you can walk closer, step back, or look around the panel.
Distance and Angular Size of Elements
In VR, everything is measured in angular degrees, not pixels or meters. The comfortable reading zone is 1.5–2 meters from the user's eyes. At that distance, the font should occupy at least 0.5° of the field of view for confident reading — that's approximately 1.5 cm of character height at 2 m.
Buttons require even larger sizes for reliable ray pressing: at least 3×3 cm physically at 2 meters — that's 0.86°. Small UI elements that work fine on a monitor become unusable in VR.
The interface should be placed in the "comfort zone" — horizontally within ±35° from the gaze direction, vertically within ±15°. A panel placed to the side or below requires constant head turning and causes fatigue.
How to Properly Configure XR Interaction Toolkit for UI
XR Interaction Toolkit (XRI) is the standard for VR interactions in Unity. For UI, it provides TrackedDeviceGraphicRaycaster (replacement for GraphicRaycaster for World Space Canvas) and XR Ray Interactor on the controller. In our projects, we use XRI version 2.5+ for support of constant angular sizes.
Basic setup: Canvas → add TrackedDeviceGraphicRaycaster, remove the default GraphicRaycaster. On the controller — XR Ray Interactor with LineType = StraightLine or ProjectileLine for a more organic look. UI Press Threshold — sensitivity of the "press" with the beam, typically 0.1–0.2 for Trigger-based interaction.
Problem with EventSystem in XRI: the default StandaloneInputModule conflicts with XRUIInputModule. The scene should have only one EventSystem with XRUIInputModule. When importing the XRI package, this is sometimes set automatically, but when working with multiple canvases, conflicts can arise — especially if part of the UI was created before XRI was added. We guarantee correct configuration of all input modules.
World Space Canvas and Texture Resolution
World Space Canvas is rendered in world coordinates through CanvasScaler with Scale Factor. The canvas texture resolution depends on the physical size of Canvas × Reference Pixels Per Unit. By default, Reference Pixels Per Unit = 100 — for a 1×0.5 m Canvas, that's 100×50 logical units. Rendered in VR, this will look blurry.
Correct setup: CanvasScaler → Scale With Screen Size is not applicable for World Space. Use Constant Physical Size with Physical Unit = Centimeters — this gives predictable element sizes independent of Canvas dimensions. Render text with TextMeshPro — its distance field rendering is significantly better than standard Unity Text when scaled in space.
Additionally: for World Space Canvas in VR, be sure to set Pixel Perfect = false (it breaks spatial rendering) and check Dynamic Pixels Per Unit in CanvasScaler — for VR, a value of 2–4 is usually needed for sharp text.
Forearm Interface: "Smartwatch" Pattern
One of the most adopted patterns in VR UI is the interface attached to the forearm of the non-dominant hand. The player raises their left hand, turns the palm toward themselves — a panel appears with inventory, map, or settings.
Implementation: Canvas as a child object of LeftHandController with local offset and rotation. Activation via Palm Up detection: use Vector3.Dot(leftHand.up, Camera.main.transform.forward) — when the value exceeds a threshold (~0.7), the hand is facing the face, show the UI.
Important: The UI should appear smoothly (Lerp alpha + scale over 0.15–0.2 s); instant appearance of a panel right in front of the eyes is jarring. And it should not activate accidentally during combat movements — need a minimum pose hold time threshold (0.3–0.5 s).
Haptic Feedback and Visual Confirmation
In VR, there is no mouse click sound and no physical button press. Without feedback, the player doesn't know if they aimed the beam at the button and pressed it.
Minimum set: visual hover state (button changes color when the beam hits), visual pressed state (button "depresses" — scale by Z by 0.05–0.1 units), haptic pulse on press via XRBaseController.SendHapticImpulse(0.3f, 0.05f). Three hundredths of a second of light vibration is enough for confirmation. Without haptics, buttons in VR feel "dead".
What's Included in the Work
| Stage | Result |
|---|---|
| Scene and requirements analysis | Document with UI placement recommendations |
| Interaction prototyping | Working prototype with basic interaction |
| XRI integration and EventSystem setup | Correctly working beams and buttons |
| Haptic feedback and animation setup | Buttons with visual and tactile feedback |
| Draw call optimization and batching | UI within FPS budget for target devices |
| Testing on target headsets | Report and bug fixes |
| Final documentation | Integration and support instructions |
Estimated Timeline
| Interface Type | Timeline |
|---|---|
| Basic World Space panel (Ray Interactor) | 3–5 days |
| UI components set (menu, inventory, HUD) | 1–3 weeks |
| Complex interface (forearm, gestures, zoning) | 3–6 weeks |
The cost is calculated individually after reviewing the design layouts and interaction scenarios. Get a consultation — contact us, we will evaluate your project within 2 business days.





