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

Мобильный VR без контроллеров требует надёжного управления взглядом, иначе пользователь быстро теряет терпение. Мы разрабатываем gaze-интерфейсы, которые делают взаимодействие естественным и отзывчивым. Наша команда реализует проект под ключ — от raycast и dwell до reticle, с учётом особенностей вашего приложения и последующей поддержкой.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

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

Мобильный 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-приложения.

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

Последние работы

  • Разработка мобильного приложения для компании FEEDME
    Разработка мобильного приложения для компании FEEDME
    1010
  • Разработка мобильного приложения для компании XOOMER
    Разработка мобильного приложения для компании XOOMER
    903
  • Разработка мобильного приложения для компании RHL
    Разработка мобильного приложения для компании RHL
    1332
  • Разработка мобильного приложения для компании ZIPPY
    Разработка мобильного приложения для компании ZIPPY
    1180
  • Разработка мобильного приложения для компании Affhome
    Разработка мобильного приложения для компании Affhome
    1107
  • Разработка мобильного приложения для компании FLAVORS
    Разработка мобильного приложения для компании FLAVORS
    714