tags: [vr-ar]
Верстка інтерфейсів ігор для пространственної взаємодії
UI у VR — не екран, який користувач бачить перед собою. Це об'єкти у просторі, з якими він взаємодіє руками або лучами. Звичайний Canvas у Screen Space працювати не буде. World Space Canvas — відправна точка, але й тут починаються складності.
Стандартна помилка: взяти UI з 2D-гри, переключити Canvas на World Space, помістити перед гравцем — і отримати панель, яка або надто близько (незручно читати у VR на дистанції 30 см), або надто далеко, або не реагує на контролери.
Дистанція та кутовий розмір елементів
У VR все вимірюється в кутових градусах, не в пікселях і не в метрах. Комфортна зона читання — 1.5–2 метра від очей користувача. На цій дистанції шрифт має займати мінімум 0.5° поля зору для впевненого чтення — це приблизно 1.5 см висоти символу на дистанції 2 м.
Кнопки вимагають ще більшого розміру для впевненого натискання лучем: мінімум 3×3 см фізичних на 2 метрах — це 0.86°. Дрібні елементи UI, які прекрасно працюють на моніторі, у VR стають неюзабельними.
Інтерфейс слід розміщувати у «зоні комфорту» — горизонтально в межах ±35° від напрямку взгляду, вертикально в межах ±15°. Панель, розміщена збоку або знизу, вимагає постійного повороту голови та стомлює.
XR Interaction Toolkit: Ray Interactor та Direct Interactor
XR Interaction Toolkit (XRI) — стандарт для взаємодій у VR на Unity. Для UI надає TrackedDeviceGraphicRaycaster (заміна GraphicRaycaster для World Space Canvas) та XR Ray Interactor на контролері.
Базова настройка: Canvas → додаємо TrackedDeviceGraphicRaycaster, видаляємо стандартний GraphicRaycaster. На контролері — XR Ray Interactor з LineType = StraightLine або ProjectileLine для більш органічного виду. UI Press Threshold — чутливість «натискання» лучем, звичайно 0.1–0.2 для Trigger-based взаємодії.
Проблема з EventSystem у XRI: стандартний StandaloneInputModule конфліктує з XRUIInputModule. У сцені має бути тільки один EventSystem з XRUIInputModule. При імпорті XRI пакету це іноді налаштовується автоматично, але при роботі з кількома canvas-ами можуть виникати конфлікти — особливо якщо частина UI була створена до підключення XRI.
World Space Canvas та розрішення текстур
World Space Canvas рендеріється в світових координатах через CanvasScaler з Scale Factor. Розрішення текстури canvas залежить від фізичного розміру Canvas × Reference Pixels Per Unit. За умовчанням Reference Pixels Per Unit = 100 — для Canvas 1×0.5 м це 100×50 умовних одиниць. При рендері у VR це буде виглядати розмито.
Правильна настройка: CanvasScaler → Scale With Screen Size не застосовується для World Space. Використовуємо Constant Physical Size з Physical Unit = Centimeters — це дає передбачуваний розмір елементів незалежно від Canvas dimensions. Текст рендеримо через TextMeshPro — його distance field рендеринг значно кращий за стандартний Unity Text при масштабуванні у просторі.
Додатково: для World Space Canvas у VR обов'язково включаємо Pixel Perfect = false (він ламає пространственний рендер) та перевіряємо Dynamic Pixels Per Unit у CanvasScaler — для VR звичайно потрібне значення 2–4 для чіткого тексту.
Інтерфейс на предплічч: паттерн «наручні годинники»
Один з найбільш прийнятих паттернів у VR UI — інтерфейс, прикріплений до предплічча недомінантної руки. Гравець піднімає ліву руку, повертає ладонею до себе — з'являється панель з інвентарем, картою або настройками.
Реалізація: Canvas як дочерній об'єкт LeftHandController з локальним зміщенням та ротацією. Активація через Palm Up detection: беремо Vector3.Dot(leftHand.up, Camera.main.transform.forward) — коли значення понад поріг (~0.7), рука повернена ладонею до обличчя, показуємо UI.
Важливо: UI має з'являтися плавно (Lerp alpha + scale за 0.15–0.2 сек), інакше миттєве появлення панелі прямо перед очима лякає. І не має з'являтися випадково при рухах у бою — потрібен мінімальний порог за часом утримання пози (0.3–0.5 сек).
Haptic Feedback та візуальне підтвердження
У VR немає звуку клику миші та немає фізичного натискання кнопки. Без зворотного зв'язку гравець не розуміє, чи попав він лучем у кнопку та натиснув її.
Мінімальний набір: візуальний hover state (кнопка міняє колір при наведенні луча), візуальний pressed state (кнопка «вдавлюється» — scale по Z на 0.05–0.1 одиниці), haptic pulse при натисканні через XRBaseController.SendHapticImpulse(0.3f, 0.05f). Трьох сотих секунди легкої вібрації достатньо для підтвердження. Без хаптики кнопки у VR відчуваються «мертвими».
| Тип інтерфейсу | Орієнтовні строки |
|---|---|
| Базова World Space панель (Ray Interactor) | 3–5 днів |
| Набір UI компонентів (меню, інвентар, HUD) | 1–3 тижні |
| Складний інтерфейс (наручний, жести, зонування) | 3–6 тижнів |
Вартість розраховується після отримання дизайн-макетів та розуміння типів взаємодій у проекті.





