Запуск одной VR-игры на Meta Quest 3 — задача. Запустить её же на Pico 4, HTC Vive XR Elite и PC через SteamVR без переписывания взаимодействий — совсем другая. Разница в API контроллеров, системах трекинга рук, разрешениях дисплеев и производительности GPU делает кроссплатформенную XR-разработку одной из самых трудоёмких задач в мобильном геймдеве. Наш опыт — более 7 лет в XR-разработке и 5 реализованных проектов — показывает: правильная архитектура с первого дня экономит до 40% бюджета в долгосрочной перспективе. Мы помогли десяткам студий избежать затратного рефакторинга, поэтому знаем, где прячутся самые коварные грабли.
Где ломается кроссплатформенность на практике
Самая болезненная точка — маппинг инпутов XR. Meta Quest использует OVRInput с кнопками PrimaryButton, SecondaryButton, PrimaryIndexTrigger. SteamVR (OpenVR) работает через Action System с файлом actions.json. OpenXR унифицирует это через Input System с InputActionAsset, но конкретные пути к кнопкам различаются: /user/hand/left/input/trigger/value для OpenXR — и это ещё относительно стандартно, но grip/pose на разных HMD имеет разный физический смысл и сдвиг позиции.
Второй кейс — hand tracking кроссплатформа. На Quest рука трекается через OVR Hand API с суставами OVRSkeleton.BoneId.Hand_Index1. На Pico — через SDK с другим именованием и другим количеством суставов в иерархии. XR Hands (пакет com.unity.xr.hands) решает эту проблему через абстракцию XRHand с XRHandJointID, но поддержка конкретных устройств зависит от версии пакета и нативного провайдера.
Третья — пространственные якоря OpenXR и Scene Understanding. Meta Spatial Anchors API, ARKit Anchors, OpenXR Spatial Anchors Extension (XR_EXT_spatial_entity) — это три разных API с разной степенью зрелости. Если приложение использует сохранение позиций объектов в реальном пространстве, архитектуру нужно строить с абстракцией над anchor API с самого начала, иначе потом рефакторинг займёт недели.
Как обеспечить кроссплатформенность XR без потери производительности?
Основа — OpenXR + Unity XR Plugin Management. OpenXR покрывает Quest (через Meta OpenXR), Pico (PicoXR OpenXR), SteamVR, Windows Mixed Reality. Для каждой платформы подключается соответствующий OpenXR Feature Package, но логика взаимодействий остаётся общей. Сравнение подходов:
| Функция |
OpenXR |
Нативные SDK |
| Инпуты |
Единый API через InputActionAsset |
Отдельные библиотеки для каждой HMD |
| Hand tracking |
Абстракция XRHand |
OVRHand, PicoHand, SteamVR_Hand |
| Пространственные якоря |
Расширение XR_EXT_spatial_entity |
Meta Spatial Anchors, ARKit Anchors |
Стек: XR Interaction Toolkit (высокоуровневые интерактивные компоненты XRGrabInteractable, XRRayInteractor, XRDirectInteractor), Unity Input System с InputActionAsset (единый маппинг, отдельный binding для каждой платформы), XR Hands (для hand tracking), AR Foundation (для AR-функций на мобильных устройствах).
Ключевой паттерн — Device Abstraction Layer: все обращения к нативным SDK оборачиваем в интерфейсы (IHandTrackingProvider, IAnchorService, IHapticFeedback). Это позволяет подключать платформенные реализации через DI без изменения игровой логики. Нативный подход с использованием OVRInput и SteamVR Action System требует в 2–3 раза больше кода по сравнению с единым OpenXR Input Action Asset.
Кейс: haptic feedback на Quest и Pico
Из конкретного кейса: в проекте с поддержкой Quest 2/3 и Pico 4 проблема возникла с haptic feedback — Meta OVR SDK поддерживает амплитуду и частоту вибрации (OVRInput.SetControllerVibration(frequency, amplitude)), а стандартный OpenXR путь через XRControllerWithRumble не давал нужной точности на Meta. Решили через feature detection: при старте проверяем наличие Meta-специфичного OpenXR Extension XR_FB_haptic_amplitude_envelope, и если он доступен — используем нативный путь, иначе — стандартный OpenXR.
Почему OpenXR — основа для кроссплатформенных XR-проектов?
OpenXR сокращает объём платформозависимого кода на 70% по сравнению с использованием нативных SDK каждого производителя. Это не просто стандарт, а активно развивающийся API — новые расширения добавляются регулярно. Мы используем официальную документацию OpenXR для актуальной информации.
Device Abstraction Layer в 3 раза ускоряет добавление новой платформы по сравнению с прямым использованием SDK, а инвестиции в кроссплатформенную архитектуру окупаются за 2–4 месяца. Экономия времени на поддержку новой платформы достигает 60%.
Тестирование XR устройств
Полноценное тестирование требует физические устройства. Но значительную часть итераций можно закрыть через: XR Device Simulator в Unity (для базовой проверки логики без HMD), Link/Air Link для Quest (запуск в PC режиме для быстрого цикла итераций), OpenXR Runtime Switcher (переключение между SteamVR и Oculus runtime на PC для сравнения поведения). Матрица тестирования фиксирует: версию ОС HMD, версию рантайма OpenXR, режим трекинга (6DoF/3DoF), работу с/без hand tracking, производительность (FPS, тепло, GPU время). Типичный FPS budget: 11 ms на Quest 2, 16.7 ms на PC VR, draw calls — не более 200 для стабильной работы.
Пошаговый план внедрения кроссплатформенности
- Аудит целевых платформ и их SDK (Meta Quest, Pico, SteamVR).
- Проектирование Device Abstraction Layer с интерфейсами под конкретные функции.
- Маппинг инпутов XR через единый InputActionAsset с bindings для каждой платформы.
- Настройка XR Interaction Toolkit и тестирование в симуляторе.
- Тестирование на физических устройствах и профилирование производительности.
- Документация и обучение команды.
Ориентировочные сроки
| Масштаб задачи |
Сроки |
| Перенос Quest-проекта на Pico (только инпуты) |
1–2 недели |
| Поддержка Quest + Pico + SteamVR с нуля |
1–2 месяца |
| Полная XR-платформа с hand tracking и anchors |
2–4 месяца |
Если вы хотите избежать типовых ошибок — свяжитесь с нами для аудита вашего проекта. Получите консультацию инженера с 10+ летним опытом в XR-разработке. Мы гарантируем качество и соблюдение сроков.
VR и AR разработка
Когда мы впервые запускаем проект в VR-гарнитуре, большинство команд сталкивается с одним и тем же: технически всё работает, но в гарнитуре либо укачивает, либо руки «плавают» с задержкой, либо сцена выглядит дёрганой на периферии взгляда. Это не баги в привычном смысле — это следствие того, что VR/AR разработка требует другого подхода к архитектуре рендера, взаимодействию и UX с самого начала проекта. Наш опыт — более 7 лет в геймдеве, 15+ завершённых VR/AR-проектов для Meta Quest, SteamVR, PSVR2, HoloLens.
Платформы и SDK
Работаем со всем актуальным стеком. OpenXR используем как базовый слой везде, где это возможно — он даёт кроссплатформенность между Meta, Valve Index, HP Reverb и другими PC VR-устройствами (OpenXR на Wikipedia). Поверх OpenXR строим на XR Interaction Toolkit (Unity) или VR Expansion Plugin (Unreal).
| Платформа |
SDK / Framework |
| Meta Quest 2/3/Pro |
Meta XR SDK, OpenXR |
| PC VR (SteamVR) |
SteamVR Plugin, OpenXR |
| PlayStation VR2 |
Sony PSVR2 SDK |
| HoloLens 2 |
Mixed Reality Toolkit (MRTK) |
| ARKit (iOS) |
AR Foundation + ARKit XR Plugin |
| ARCore (Android) |
AR Foundation + ARCore XR Plugin |
| WebXR |
Unity WebXR Export |
Как минимизировать укачивание при локомоции в VR?
Locomotion — главный источник motion sickness для неопытных VR-пользователей. Согласно исследованиям, около 70% пользователей испытывают дискомфорт при неправильной настройке движения (Oculus Developer Guidelines). Teleportation — стандартный способ навигации, когда плавное передвижение нежелательно.
Компоненты из XR Interaction Toolkit: TeleportationArea, TeleportationAnchor, TeleportationProvider. Базовая реализация работает «из коробки», но для продакшна дорабатываем её в четыре шага:
- Настройка
XRRayInteractor с изогнутым лучом (Bend Ray) — дуга телепортации выглядит натуральнее прямого луча, лучше считывается пользователями.
- Добавление валидной зоны приземления — визуальный индикатор меняет цвет при наведении на препятствие (красный/зелёный).
- Внедрение fade transition — плавное затухание экрана (black fade) перед телепортом снижает дезориентацию.
- Rotation snapping — после телепорта предлагаем snap-поворот на 45° или 90° вместо плавного, что снижает риск укачивания.
Для проектов, где нужна плавная локомоция (экшн-игры, симуляторы), используем comfort settings: виньетирование при движении, снижение FOV во время ускорения. Настройки доступны пользователю в меню — разные люди имеют разный порог чувствительности.
Детали реализации: Kinematic vs Physics-based movement
При захвате объекта ключевой выбор — Kinematic (мгновенное следование за рукой) или Physics-based (удержание через Joint). Первое отзывчиво, но объекты проходят сквозь стены. Второе даёт реалистичные коллизии, но при быстрых движениях joint «растягивается» — потребуется velocity damping и max joint force.
Как сделать захват объектов в VR физически реалистичным?
Это самая недооценённая часть VR-разработки. Клиенты часто воспринимают её как «просто анимация рук», но на практике — сложная система, где физическая корректность, отзывчивость и комфорт вступают в противоречие.
Grab (захват)
XR Interaction Toolkit предоставляет три типа Interactable для захвата:
-
XRGrabInteractable — стандартный захват, объект следует за контроллером через физический joint или direct position/rotation
-
XRSimpleInteractable — для объектов без физического перемещения (кнопки, рычаги)
- Кастомные Interactable через наследование от
XRBaseInteractable
Attach Transform — часто игнорируемая деталь. У каждого Interactable должен быть правильно настроенный Attach Transform (точка, к которой рука «прилипает»). Без него рукоятка пистолета окажется по центру меша, а не там, где её держат.
Для оружия и инструментов с двуручным захватом — отдельная система TwoHandGrab: ведущая рука определяет позицию, вторая — ориентацию. XR Interaction Toolkit поддерживает это через XRTwoHandGrabInteractable или кастомную логику с двумя Attach Points.
Throw (бросок)
Почему velocity smoothing критично для реалистичного броска? Проблема в том, что Rigidbody.velocity в момент отпускания контроллера отражает мгновенную скорость, которая часто некорректна из-за дискретизации трекинга. Пользователь делает быстрое движение запястьем — а объект летит вдвое медленнее.
Решение: velocity smoothing за последние N кадров (типично 5-10 кадров, ~80-160 мс при 60 Hz) перед отпусканием. XR Interaction Toolkit делает это через VelocityEstimator. Дополнительно применяем velocity scaling multiplier — небольшое умножение скорости (1.2-1.5x) делает броски субъективно более удовлетворительными. Угловую скорость (для объектов, которые должны крутиться в полёте) тоже усредняем аналогичным образом.
AR: Plane Tracking и работа с окружением
AR добавляет другой класс проблем — работу с реальным, непредсказуемым окружением. AR Foundation — кроссплатформенный слой поверх ARKit и ARCore. Большинство базовых функций (plane detection, raycasting, image tracking, face tracking) доступны через единый API.
Plane Detection
ARPlaneManager обнаруживает горизонтальные и вертикальные плоскости. Практические нюансы:
- Инициализация занимает время — пользователь должен осмотреть помещение, пока система строит карту. Нужен явный onboarding с инструкцией «медленно поводите камерой по поверхностям».
- Плоскости нестабильны — их границы и позиция обновляются по мере накопления данных. Объекты, размещённые на плоскости, нужно привязывать через
parenting к ARPlane, а не к мировым координатам.
- Слияние плоскостей — два обнаруженных сегмента пола могут слиться в один, что двигает якорь. Для критичных якорей используем
ARAnchor вместо прямой привязки к плоскости.
Детали Image Tracking
ARTrackedImageManager — для маркеров. Качество трекинга напрямую зависит от качества reference image. Изображения с высокой частотой деталей и контрастными краями (как QR-код, но красиво) трекаются надёжнее, чем гладкие логотипы. ARCore Geospatial API — для outdoor AR с привязкой к реальным координатам (точность до 10 см в хорошо картированных зонах).
Оптимизация для VR: фреймрейт и комфорт
VR требует стабильного высокого фреймрейта. Около 60% времени разработки в мобильном VR уходит на оптимизацию, а не на функционал — ретрофит в два раза дороже правильной архитектуры с первого спринта.
| Устройство |
Целевой Hz |
Критический порог |
| Meta Quest 2 |
72 / 90 Hz |
< 72 Hz — заметно |
| Meta Quest 3 |
90 / 120 Hz |
< 90 Hz — заметно |
| Valve Index |
90 / 120 / 144 Hz |
< 90 Hz — заметно |
| PSVR2 |
90 / 120 Hz |
< 90 Hz — заметно |
Single Pass Instanced Rendering
Главная оптимизация рендера в VR. Без неё сцена рендерится дважды (для каждого глаза), что удваивает draw calls. Single Pass Instanced рендерит оба глаза за один проход через instancing: geometry обрабатывается один раз, шейдер получает два view/projection matrix через GPU instancing. Включается в Unity через XR Plug-in Management > Rendering Mode: Single Pass Instanced. Важно: кастомные шейдеры должны поддерживать SPI — стандартные URP/HDRP шейдеры поддерживают, кастомные HLSL требуют правки (UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX и связанные макросы). Применение этой техники сокращает количество draw calls на 40-50%.
Foveated Rendering
На Meta Quest доступен Fixed Foveated Rendering (FFR) — снижение разрешения на периферии кадра, где острота восприятия ниже. Настраивается через OVRManager или Meta XR SDK:
OVRManager.fixedFoveatedRenderingLevel = OVRManager.FixedFoveatedRenderingLevel.High;
OVRManager.useDynamicFixedFoveatedRendering = true;
Dynamic FFR автоматически повышает уровень при просадке фреймрейта — удобнее фиксированного в сценах с переменной нагрузкой.
IPD и Comfort Settings
IPD (Inter-Pupillary Distance) — расстояние между зрачками, влияет на восприятие глубины. На программируемом уровне в большинстве устройств доступно только чтение IPD (OVRPlugin.GetSystemDisplayFrequency), физическая настройка — на гарнитуре. Для приложений с точным позиционированием (медицинские симуляторы, тренинги) учитываем IPD в расчётах масштаба сцены.
Haptics
Тактильный фидбек — недооценённый инструмент. Даже простой вибрационный отклик при захвате объекта или попадании значительно повышает ощущение присутствия. В среднем интеграция тактильных паттернов занимает 30–80 часов на проект.
XR Haptics через OpenXR:
var hapticImpulse = new UnityEngine.XR.HapticCapabilities();
InputDevice device = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
device.SendHapticImpulse(0, amplitude: 0.5f, duration: 0.1f);
Для сложных паттернов (тактильная «текстура» поверхности при прикосновении, нарастающая вибрация при натяжении тетивы лука) используем Meta Haptics Studio — позволяет дизайнить haptic-клипы визуально.
Что входит в разработку VR/AR-приложения
При заказе проекта под ключ мы предоставляем:
- Архитектурный документ с описанием стека, логики рендера и системы взаимодействия
- Рабочий прототип (MVP) для тестирования на целевом устройстве
- Интеграцию необходимых SDK (Meta XR, OpenXR, AR Foundation и др.)
- Оптимизацию под целевые частоты 72/90/120 Hz с профилированием draw calls и FPS
- Тестирование на физическом оборудовании (Quest, SteamVR, HoloLens) с привлечением пользователей
- Полную документацию по сборке, деплою и поддержке
- Обучение команды заказчика (воркшоп по работе с XR Toolkit)
- Гарантийную поддержку в течение 1 месяца после сдачи
Что влияет на стоимость и сроки
VR/AR проекты дороже обычных игр аналогичного объёма. Итерации медленнее — каждую правку нужно тестировать в гарнитуре, эмулятор не передаёт реальный опыт. Motion sickness вынуждает переделывать часть концептуальных решений после первого плейтеста. Оптимизация занимает существенную долю времени — для мобильного VR (Quest) до 60-70% цикла. Для проектов под Quest начинаем оптимизацию с первого спринта. Стоимость интеграции базового SDK (XR Interaction Toolkit) обычно варьируется от 200 000 до 600 000 рублей в зависимости от объёма кастомных Interactable. Средний бюджет полного проекта под Quest составляет от 1 500 000 до 4 000 000 рублей.
Получите консультацию по вашему проекту — оценим задачу, стек и сроки. Закажите разработку VR/AR-приложения под ключ с гарантией стабильного фреймрейта.