Розробка gaze-інтерфейсу для мобільного VR: raycast, dwell, reticle

Мобільний VR без контролерів — єдиний спосіб взаємодії — напрямок погляду. Здається, просто дивись на кнопку — вона натискається. На практиці неправильно реалізований gaze дратує користувача швидше за будь-який інший UI-паттерн. За роки роботи ми виробили стек та підходи, що гарантують комфортну вза

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Розробка gaze-інтерфейсу для мобільного VR: raycast, dwell, reticle
Середній
~3-5 днів

Наші компетенції:

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    597

Мобільний VR без контролерів — єдиний спосіб взаємодії — напрямок погляду. Здається, просто дивись на кнопку — вона натискається. На практиці неправильно реалізований gaze дратує користувача швидше за будь-який інший UI-паттерн. За роки роботи ми виробили стек та підходи, що гарантують комфортну взаємодію. Наш досвід — 5+ років у мобільній VR-розробці, понад 20 проєктів з gaze-інтерфейсом. Ми пропонуємо готове рішення під ключ: від raycast до прогрес-індикатора. Базову систему реалізуємо за 3–5 днів, повну — за 1–2 тижні. Згідно з документацією Google Cardboard, gaze-based interaction є стандартним методом введення для мобільного VR без контролерів.

Як працює raycast з центру погляду?

Gaze визначається напрямком погляду камери. Ray пускається з позиції камери вперед по Camera.main.transform.forward:

void FixedUpdate() { Ray gazeRay = new Ray(Camera.main.transform.position, Camera.main.transform.forward); if (Physics.Raycast(gazeRay, out RaycastHit hit, maxGazeDistance, interactableLayer)) { var target = hit.collider.GetComponent<IGazeTarget>(); if (target != null) { HandleGazeHit(target, hit.point); } else { HandleGazeMiss(); } } else { HandleGazeMiss(); } } 

FixedUpdate() замість Update() — стабільна частота викликів не прив'язана до FPS. На слабких пристроях при просіданнях до 30 FPS Update() дає нерівномірний відгук. Шар interactableLayer — обов'язково: raycast по всій сцені дорого, і користувач не повинен випадково активувати невидимі колайдери.

Як реалізувати reticle (курсор погляду)?

Reticle — візуальний індикатор точки погляду. Розміщується в world space на поверхні об'єкта під поглядом. Відстань динамічна: reticle «прилипає» до хітпойнту.

void UpdateReticle(Vector3 hitPoint, Vector3 hitNormal) { reticleTransform.position = hitPoint + hitNormal * RETICLE_OFFSET; reticleTransform.rotation = Quaternion.LookRotation(-hitNormal); // Масштаб постійний у кутових одиницях (constant apparent size) float dist = Vector3.Distance(Camera.main.transform.position, hitPoint); reticleTransform.localScale = Vector3.one * dist * ANGULAR_SIZE; } 

Зазначимо: коли об'єкта під поглядом немає — reticle на дефолтній відстані (3–5 метрів). Не ховаємо його: користувач завжди повинен бачити, куди дивиться.

Dwell-активація та прогрес-індикатор

Користувач дивиться на об'єкт N секунд — відбувається активація. Оптимальний час dwell: 1.2–2.0 секунди. Менше 1 секунди — випадкові активації при огляді сцени, більше 2 секунд — втомлює. Прогрес має бути помітним. Кільце, що заповнюється навколо reticle — стандарт:

public class GazeDwellController : MonoBehaviour { [SerializeField] private float dwellTime = 1.5f; [SerializeField] private Image progressRing; private float dwellProgress = 0f; private IGazeTarget currentTarget; private bool isActivated = false; public void OnGazeEnter(IGazeTarget target) { currentTarget = target; dwellProgress = 0f; isActivated = false; progressRing.gameObject.SetActive(true); } public void OnGazeStay() { if (isActivated) return; dwellProgress += Time.deltaTime / dwellTime; progressRing.fillAmount = dwellProgress; if (dwellProgress >= 1f) { isActivated = true; currentTarget?.OnGazeActivate(); StartCoroutine(ResetAfterDelay(0.5f)); } } public void OnGazeExit() { currentTarget = null; progressRing.gameObject.SetActive(false); dwellProgress = 0f; } } 

Після активації — короткий cooldown перед наступною активацією того самого об'єкта (0.5–1.0 сек). Інакше користувач не встигає прибрати погляд і кнопка «натискається» двічі.

Hover-стан: зворотний зв'язок до активації

Зазначимо: коли користувач дивиться на об'єкт, але dwell ще не завершено, потрібен негайний візуальний зворотний зв'язок. Об'єкт повинен якось відреагувати при OnGazeEnter — до завершення часу активації. Варіанти:

  • Підсвітка: зміна emission кольору матеріалу
  • Масштаб: об'єкт трохи збільшується (0.05f вистачає)
  • Анімація: іконка реагує на погляд
  • Звуковий сигнал: короткий click на початку dwell

Без цього користувач не розуміє, чи «бачить» його застосування.

Cardboard button як підтвердження

У Cardboard є фізична кнопка (магнітний тригер). Додаємо її як альтернативний метод активації замість dwell — для досвідчених користувачів це швидше та зручніше:

// Cardboard SDK trigger event void Update() { if (CardboardInput.GetButtonDown()) { TriggerCurrentGazeTarget(); } } 

Кнопка — не заміна dwell, а доповнення. Не всі корпуси Cardboard мають робочу магнітну кнопку.

Які типові помилки виникають при gaze-взаємодії?

Занадто маленький колайдер інтерактивного об'єкта — користувач «промахується» повз кнопку. Колайдер має бути на 10–20% більший за видимий об'єкт. Швидкість погляду (кутова швидкість) впливає на точність: при швидкому огляді поріг швидкості скидає dwell. Reticle тремтить через гіроскоп — Lerp з часом 20 мс усуває тремтіння. Використовуйте окремий шар для raycast, щоб уникнути випадкових активацій та заощадити продуктивність.

Помилка Рішення
Занадто маленький колайдер Збільшити колайдер на 10–20% відносно візуалу
Випадкові активації Поріг кутової швидкості голови при старті dwell
Тремтіння reticle Lerp позиції reticle з time ~20ms

Порівняння методів активації

Параметр Dwell-активація Cardboard кнопка
Готовність на всіх пристроях Так Ні (не у всіх працює)
Втомлюваність Середня Низька
Точність Добра Висока
Налаштування часу Так (1.2–2.0 с) Ні

Що входить у роботу

  • Документація архітектури gaze-системи
  • Вихідний код: raycast, reticle, dwell controller, hover-стан
  • Інтеграція з Cardboard SDK та альтернативними тригерами
  • Тестування на пристроях (iOS/Android) з різними версіями Cardboard
  • Підтримка 2 тижні після здачі

Процес роботи

  1. Аналіз інтерактивних елементів: типи об'єктів, сценарії взаємодії.
  2. Реалізація raycast-системи з правильними шарами та колайдерами.
  3. Reticle в world space з constant apparent size.
  4. Dwell controller з прогрес-індикатором, hover-станом, cooldown.
  5. Cardboard button як альтернативний тригер.
  6. Тестування комфорту: час dwell, розміри кнопок, зворотний зв'язок.

Орієнтири за термінами

Базова gaze interaction система з reticle та dwell — 3–5 днів. Повноцінна система з кількома типами інтерактивних об'єктів, анімаціями, звуком та налаштовуваними параметрами — 1–2 тижні.

Гарантуємо комфортну взаємодію. Сертифіковані розробники Unity та Android/iOS. Зв'яжіться з нами, щоб обговорити ваш проєкт — реалізуємо gaze-інтерфейс для вашого мобільного VR-застосування.