Мониторинг ошибок и крэш-репортов в мобильных VR играх
Мобильный VR — Quest 2/3 standalone, Pico 4, устаревший Cardboard — имеет специфику, которая делает мониторинг крэшей сложнее, чем в десктопных играх. Устройство автономное, логи не видны в реальном времени, пользователь не знает, что произошло, а developer console далеко. Если в сборку не встроен crash reporting заранее, после релиза вы работаете практически вслепую.
Почему стандартный Unity Crash Reporter не работает для VR
Unity Cloud Diagnostics (старый Unity Analytics) и встроенный UnityCrashHandler покрывают C#-исключения и manageable крэши. Но мобильный VR-крэш часто происходит глубже — в нативном слое: драйвер GPU, Vulkan runtime, Oculus platform layer. Эти крэши приходят как SIGSEGV или SIGABRT с hex-стеком, который без NDK symbolication не читается.
Конкретный пример: Quest 2, Unity 2022.3 LTS, URP, крэш происходил на устройствах с конкретной прошивкой Horizon OS v57. Стек из logcat: #00 pc 0x00000000012abc14 /data/app/com.yourcompany.game/lib/arm64/libunity.so. Без symbol table от соответствующей версии Unity это ничего не говорит. С symbol table (лежат на Unity Download Archive для каждой LTS версии) — раскрывается в конкретный вызов внутри Vulkan buffer allocation, который лёг из-за изменения memory limits в Horizon OS v57.
Для IL2CPP-сборок — нужны .pdb файлы или il2cpp_data директория из билда для правильного symbolication C#-части стека. Без них Firebase Crashlytics покажет нативный стек без маппинга на C#-классы.
Инструменты и настройка
Firebase Crashlytics — стандарт де-факто для мобильного VR. Интегрируется через Firebase Unity SDK. Требует google-services.json в проекте и настройки в launcherTemplate.gradle. Crashlytics автоматически собирает нативные и managed крэши, группирует по стеку, показывает trending.
Ключевые настройки для Android/Quest: включить android.useNewApkSplitting если используется asset bundling, чтобы Crashlytics корректно маппил версии. Загрузка NDK symbols — через Firebase CLI: firebase crashlytics:symbols:upload --app=APP_ID path/to/libil2cpp.so.
Sentry Unity SDK — альтернатива с более гибкой on-premise опцией. Полезно для студий с требованиями к хранению данных в конкретной юрисдикции. Настройка через Sentry.Init() в первой MonoBehaviour с release и environment тегами — позволяет фильтровать крэши по версии и каналу (dev/staging/production).
Дополнительно к crash reporting — custom event logging для отслеживания soft errors: ситуаций, когда крэша нет, но поведение неправильное. Analytics.CustomEvent("tracking_lost", {"duration": 5.2, "lighting": "low"}) — позволяет видеть паттерны деградации трекинга без крэша.
Разбор крэш-репортов и установление приоритетов
После настройки мониторинга — регулярный цикл разбора. Группировка крэшей по версии приложения, версии OS, модели устройства. Для Quest — отдельная фильтрация по версии Horizon OS: некоторые крэши появляются строго на определённой прошивке.
Метрика crash-free rate (% сессий без крэша) — основной KPI. Для VR-приложений норма: >99% на поддерживаемых устройствах. Если ниже 97% — активное расследование.
Типичные причины крэшей в мобильном VR:
- Out of memory: 6 GB RAM у Quest 3 — звучит много, но Horizon OS оставляет приложению около 3–4 GB. Утечки нативной памяти, некорректный unload AssetBundle, накопление texture memory в addressables cache — всё это ведёт к OOM kill.
- Vulkan validation errors в дев-сборках становятся крэшами в release, если
GraphicsDeviceTypeпереключён без проверки совместимости шейдеров. - Threading violations: обращение к Unity API из non-main thread без
UnityMainThreadDispatcherили аналога.
| Задача | Ориентировочные сроки |
|---|---|
| Интеграция Firebase Crashlytics с symbolication | 1–2 рабочих дня |
| Настройка полного monitoring stack (Crashlytics + Sentry + custom events) | 3–5 рабочих дней |
| Разбор и исправление топ-5 крэшей после интеграции | 1–3 недели (зависит от сложности) |
Стоимость рассчитывается после анализа проекта и текущего состояния мониторинга.





