Решение технических и производственных проблем в Laser Matrix

Мариус Торвальдсен, Мартин Сивертсен и Синдре Аским Гронволь основали Breach в 2016 году, чтобы создавать погружающие игры, XR-опыты и 3D-симуляции. За последние девять лет студия по найму предоставила XR решения, а также разрабатывала свои собственные игры. В 2024 году они начали генерировать идеи и начали прототипирование, ища новый внутренний проект. Одна игровая концепция быстро перешла в производство и стала Laser Matrix.
Название — это игра-головоломка смешанной реальности, где фитнес, развлечение и футуристические вызовы сталкиваются. Игроки могут решать головоломки на основе света, уклоняться от движущихся лазеров и открывать уровни, используя свою ловкость и смекалку.
Мы встретились с Андреасом Вейбе, директором по инженерии в Breach, и Йонасом Йоргенсеном, одним из разработчиков игр, чтобы обсудить создание игры для Meta Quest и Android XR, а также то, как они преодолели технические и производственные проблемы.
Что такое Laser Matrix?
Андреас: Laser Matrix — это игра-головоломка с движением в VR. Она очень аркадная и может превратить вашу гостиную в опасный лабиринт, в котором вам нужно быстро и ловко передвигаться.
Как проходил процесс реализации для Meta Quest и Android XR?
Андреас: Мы не реализовывали Meta Quest и Android XR одновременно с начала проекта. Прототип изначально был только для Meta Quest. Мы много работали с платформой, поэтому быстро запустили её. Android XR также не существовал, когда мы начали этот прототип, поэтому мы в итоге портировали его в процессе разработки.
Йонас: Мы начали с инструмента "строительный блок" от Meta для быстрого прототипирования. Это сделало проверку концепции более удобной. В конечном итоге мы поняли, что хотим нацелиться на кроссплатформенный XR и убедились, что структура игры более независима от платформы. Основной игровой процесс не зависит от специфических функций платформы, поэтому переход на кроссплатформенность был легким.

Какие шаги вы предприняли при реализации отслеживания рук в OpenXR?
Йонас: Мы считывали данные отслеживания в реальном времени из OpenXR runtime. Данные затем обрабатываются через абстракционные слои, где сырые данные преобразуются в позиции и вращения, которые затем применяются к сеткам рук. Эти сетки рук затем взаимодействуют с встроенными системами взаимодействия в Unity, которые предоставляют утилиты для общих действий, таких как прикосновение к чему-либо пальцем. Затем, наконец, наши собственные игровые слои поверх этого.
Все дело в многослойной абстракции от этих сырых данных. Многие XR-игры часто имеют схожие потребности, поэтому мы старались использовать стабильные существующие решения как можно больше и аккуратно их связывать. Для Лазерной матрицы нет много нестандартных аспектов отслеживания рук.

С какими техническими проблемами столкнулась команда?
Андреас: Это довольно стандартная настройка OpenXR, когда дело касается сцены и используемых компонентов. Нам пришлось обойти проблемы, связанные с моментами, когда руки теряют или получают отслеживание и появляются в другом месте в этом кадре. В какой-то момент игроки начали терять отслеживание рук, что привело к потере жизней.
Йонас: Проектирование с учетом отслеживания рук было одной из больших проблем. Разные контактные точки на руке вызвали некоторые проблемы. Это более просто для нормальных, медленных взаимодействий пользовательского интерфейса, таких как нажатие кнопки. Однако в Лазерной Матрице вы постоянно двигаете своим телом и головой, что может снизить точность отслеживания рук на основе камеры.
Андреас: Для пользовательского интерфейса вне игрового процесса мы реализовали кнопки, которые нужно касаться пальцами, в отличие от использования трассировки лучей. По нашему опыту, трассировка лучей с отслеживанием рук недостаточно точна для отличного игрового опыта, поэтому это помогло.
Йонас: Для игр на "плоском экране" разработчики могут ограничить, как используются вводы, такие как мышь, клавиатура и контроллеры. XR отличается, потому что игра никогда не может по-настоящему остановить ваши физические руки. Например, кнопки в меню Лазерной Матрицы довольно плоские, и вы можете проткнуть свою руку через кнопку. Это взаимодействие, для которого вы не обязательно проектируете, и неясно, что должно на самом деле произойти. Это действительное нажатие кнопки? В общем, есть некоторые интересные последствия, которые следуют, когда вы переводите более традиционные шаблоны пользовательского интерфейса в XR.

С какими проблемами, связанными с производительностью, столкнулась команда?
Андреас: Наша основная проблема с производительностью связана с графической стороной. С самого начала речь идет о нахождении баланса с прозрачностью наложения. Это одна из самых больших проблем с текущим дизайном игры, потому что если бы вы использовали только контуры для этих коробок, вы могли бы видеть, где они находятся, когда смотрите вверх или вниз и сравниваете их с чем-то. Но когда вы смотрите прямо вперед и пытаетесь понять свое расстояние до стены или насколько далеко вы можете вытянуть руку, не касаясь, это сложнее.
Поскольку мы хотим, чтобы пользователь мог видеть весь лабиринт одновременно и принимать стратегические локальные решения, нам нужно решение по прозрачности или альтернатива, обе из которых требуют много ресурсов GPU.
Йонас: Некоторые из наших решений повлияли на финальные визуальные эффекты игры. Например, мы изменили внешний желтый контур игровой области. Ранее он имел прозрачный желтый оттенок, покрывающий всю поверхность стены, но мы уменьшили его только до краев, с градиентным переходом к полной прозрачности. Поскольку граница игры видна в любое время во время игры, это постоянно снижало количество вызовов перерисовки, что было одной из основных причин времени кадра.
Мы также рассмотрели красные лазерные кубы, которых игрок пытается избежать, перемещаясь по игре. На их поверхности есть квадратный узор сетки. Мы могли бы применить тот же подход, что и с желтым кубом границы, снова пытаясь уменьшить перерисовку. Поскольку только края ячеек сетки полностью отрисовываются, мы сделали ячейки больше, что в среднем привело к тому, что большая часть поверхности стала полностью прозрачной.
Также были некоторые проблемы с производительностью, связанные с загрузкой. Каждый раз, когда уровень начинался, происходил большой всплеск. Сначала мы просто предположили, что это связано с загрузкой уровней в целом. Загрузка уровня Laser Matrix означает, что необходимо создать много различных элементов. Однако виновником была именно музыка. При профилировании мы обнаружили, что система перезагружала аудио с каждым уровнем. Мы настроили его на предварительную загрузку музыки с приложением, что сделало всплеск незаметным.
Андреас: Некоторые из наших проблем с производительностью возникли из-за того, что мы превратили прототип в производственную игру. Нам следовало бы переписать систему.

Какие инструменты и функции Unity были важны во время сборки?
Андреас: Преимущество Unity заключается в том, что он позволяет нам создать один актив и один кусок кода и сделать так, чтобы он работал на нескольких платформах с самого начала.
VFX Graph был отличным, потому что он позволил нашему владельцу продукта, который не имеет художественного уклона, набросать то, как он представлял визуальные эффекты. Оттуда наш технический художник и разработчик доработали его.
Йонас: Shader Graph был очень ценным инструментом для создания игры. Большинство 3D элементов игры являются чистыми шейдерами. Помимо некоторых кубов, рук и кнопок, в этой игре очень мало настоящих 3D моделей.
XR Device Simulator также использовался очень часто. Когда вы работаете в XR, тестирование может быть довольно физическим и утомительным в долгосрочной перспективе. Между всеми шагами – вставанием, надеванием гарнитуры, передвижением и многим другим – часы действительно накапливаются. Настроив симулятор и используя ввод с мыши для стимуляции взаимодействий, мы сэкономили много времени и нервов.
Андреас: Поскольку у меня был XR Device Simulator с самого начала, я хотел разрабатывать новые функции так, чтобы их было легче тестировать в изоляции. Это подтолкнуло меня писать более модульные, тестируемые системы с самого начала, что также улучшило качество нашего кода.
Йонас: Unity Profiler также сыграл ключевую роль в том, чтобы помочь нам определить, откуда возникли всплески производительности. Например, с проблемой загрузки аудио, о которой я упоминал, Profiler помог нам как определить всплеск, так и вызовы, которые были инициированы в это точное время. Этот вид информации обычно дает четкие подсказки о том, с чего следует начать при реализации решения.

Какие новые функции или обновления в Unity 6 были наиболее полезными?
Йонас: Мы собираем для довольно многих целей и в разных контекстах. При переходе на разные платформы нам нужны сборки с разными конфигурациями для специфичных для платформы функций и сервисов. Таким образом, возможность иметь профили сборки в Unity 6 позволила нам адаптировать наши сборки для этих разных платформ. Делать это вручную было бы утомительно и подвержено ошибкам.
Какие ключевые показатели производительности у вас были?
Йонас: Когда мы отметили проблемы с производительностью, что является большой проблемой в XR, особенно из-за укачивания, мы измерили средний fps и искали падения кадров. Существуют четко определенные цели для того, что комфортно, а что нет.
Настраивая пороги на различных шейдерах кубов, мы получили около 10% в fps. Мы профилировали игру в тестовой среде, где мы нарисовали максимальное количество кубов для игры. Это предоставило нам очень фиксированный и надежный контекст для тестирования.
Андреас: Для производительности наши жесткие ограничения составляют 72 fps на Meta Quest 2 и 90 fps на Meta Quest 3. Мы нацелены на среднюю частоту кадров, но можем создать ситуации, когда пользователь получает более низкий результат. Это очень специфические случаи, когда вы можете оказаться в худшем возможном месте.
Йонас: На более проектном и командном уровне наше время итерации стало гораздо более эффективным за последние несколько месяцев. Как компания, мы улучшили наш процесс обеспечения качества и связали его с нашей автоматизацией, и теперь наш цикл обратной связи и исправлений довольно быстрый. Мы можем решать проблемы достаточно быстро, чтобы очередь задач не накапливалась и не выходила из-под контроля.

Есть ли что-то, что команда хотела бы сделать иначе в процессе разработки?
Андреас: Нам следовало начать использовать OpenXR немного раньше. В начале проекта мы планировали использовать функцию разметки комнат Meta, чтобы определить форму и размер игровой зоны. Хотя это работало, это не дало нам функциональности игрового процесса, которую мы искали, не открывая при этом дизайнерские проблемы, для которых у нас еще не было хороших решений. Мы поняли это во время обсуждения сканирования комнаты. Нам следовало отказаться от этой системы раньше, потому что мы слишком долго пытались ее решить. Кроме того, оглядываясь назад, как только прототипный код эволюционировал в производственный код, осознание того, что система больше не служила дизайну, сэкономило бы время.
Чтобы узнать больше о проектах, сделанных с помощью Unity, посетите страницу Ресурсы.
