Назад к блогу

Godot на XREAL AURA: практическое руководство по нативной пространственной разработке

Опубликовано 3 ноября 2026 г.
Godot на XREAL AURA: практическое руководство по нативной пространственной разработке Создано с помощью ИИ

Коротко о главном

Освойте Godot на XREAL AURA: редактор на очках, OpenXR Spatial Containers, дрейф якоря и лучшие практики нативной пространственной разработки.

Ваш текущий конвейер сборки XR означает привязку к десктопу, экспорт APK, sideloading через ADB, надевание гарнитуры, обнаружение опечатки и начало заново. XREAL AURA полностью убирает этот цикл, а Godot входит в стартовый набор с полноценным редактором, который работает прямо на очках. Это меняет смысл слова «итерация» для пространственной разработки.

В этом руководстве разобран реальный процесс: запуск редактора на AURA, структурирование пространственной сцены с помощью OpenXR Spatial Containers, работа с моделью passthrough/see-through, которая отличает оптические очки от VR-гарнитур, и ловушки, которые подстерегают вас при первом экспорте.

Почему оптический see-through меняет ваши проектные допущения

XREAL AURA — первое устройство с оптическим see-through на Android XR. Это одно предложение ломает допущения, заложенные в большинство туториалов по Godot XR.

В VR-гарнитуре камера гарнитуры рендерит всё. Пользователь видит ваше окружение и больше ничего. На очках с оптическим see-through пользователь смотрит сквозь линзы на реальный мир, а ваш отрендеренный контент накладывается поверх. Это не то же самое, что видео passthrough на Quest — видео passthrough захватывает реальность камерами и выводит её заново, что создаёт задержку и потери света. Оптический see-through даёт нулевую задержку композитора для реального мира.

Практические последствия для вашего бюджета рендеринга:

  • Вы не можете затемнить реальный мир. Чёрный на прозрачном дисплее прозрачен. У вас нет непрозрачного фона, поэтому интерфейс, который полагается на контраст с тёмными панелями, не сработает в яркой комнате.
  • Выигрывает контент, выглядящий аддитивно. Яркий эмиссивный контент хорошо читается; тёмный, ненасыщенный исчезает. Стройте палитру с яркостью в 2–3 раза выше, чем в VR.
  • Поле зрения уже, чем в VR. Контент, размещённый под экстремальными углами, оказывается за пределами области дисплея. Держите основные интерактивные цели в пределах примерно ±30 градусов от центра вперёд.

Если вы уже выпускали VR, ожидайте перенастройки каждого материала и каждой UI-панели. Заложите на это полный день на сцену.

Установка редактора Godot на очки

Редактор распространяется через Google Play, а не в виде sideload-APK. Это важно: вы можете обновлять его как любое другое приложение.

Порядок настройки:

  1. Установите редактор Godot на XREAL AURA из Play Store.
  2. Установите сопутствующее приложение со средой сборки Gradle. Оно поставляется с тулчейном экспорта Android, поэтому вам не придётся собирать JDK и Android SDK с нуля на устройстве.
  3. Войдите в аккаунт Android-разработчика, если планируете подписывать и публиковать сборки с устройства.
  4. Запустите редактор — он открывается в многоконном пространственном рабочем пространстве, а не в одном плоском окне.

Четвёртый пункт — самый интересный. Редактор даёт вам набор функций в стиле десктопа, но в виде плавающих окон в пространстве. Можно держать дерево сцены в одном объёме, а 2D-вьюпорт в другом.

Что на самом деле даёт вам рабочий процесс на устройстве

Честный ответ: быстрая итерация по ощущениям, медленная — по ассетам.

Редактирование шейдеров, изменение трансформов узлов и тестирование привязок ввода на целевом устройстве устраняет весь цикл экспорт-тест. Этот цикл обычно занимает 3–8 минут с учётом времени сборки, передачи и повторного запуска. Десять итераций — это потерянный час.

Что оно не ускоряет: импорт больших атласов текстур, длительный запекание карт освещения (lightmap) и всё, что требует интенсивной работы CPU. Это делайте на рабочей станции. Реалистичное разделение: создание ассетов на десктопе, сборка сцены и настройка — на очках.

Создание пространственного контента с помощью OpenXR Spatial Containers

Поддержка Android XR в Godot включает OpenXR Spatial Containers — управляемые системой объёмы, в которые ваше приложение помещает пространственный контент. Аналогия самой платформы почти точна: традиционные приложения рисуют 2D-контент в окнах на десктопе; пространственные приложения рисуют 3D-контент внутри контейнеров в комнате.

Есть два типа контейнеров, которые стоит понять до написания кода:

Тип контейнера Для чего лучше всего Компромисс
Volume 3D-объекты с реальной глубиной, привязка к миру Система может ограничивать границы объёма
Panel UI-поверхности, текст, 2D-игры Рендерится в фиксированной плоскости; глубина плоская

Большинство разработчиков ошибочно выбирают volume для UI. Текст в объёмном контейнере система масштабирует и перемещает непредсказуемо, а ваш аккуратно размещённый виджет радара уплывает. Помещайте UI в контейнер panel и позвольте системе управлять размещением.

Работа с API пространственных контейнеров

Godot предоставляет пространственные контейнеры через классы расширений OpenXR. Точные имена классов зависят от версии Godot, поэтому перед написанием продакшн-кода проверьте список функций движка для текущих привязок пространственных контейнеров. Приведённый ниже паттерн отражает типичную структуру XR-контента на основе контейнеров.

extends Node3D

signal container_created(handle: int)

# Spatial container setup for Android XR.
# Class names are version-dependent; verify against the
# OpenXR extension bindings shipped with your Godot build.

var volume_container: SpatialContainer
var panel_container: SpatialContainer

func _ready() -> void:
    var xr_interface: XRInterface = XRServer.find_interface("OpenXR")
    if xr_interface == null or not xr_interface.is_initialized():
        push_error("OpenXR interface unavailable on this device.")
        return

    # Volume container for the 3D board.
    volume_container = SpatialContainer.new()
    volume_container.container_type = SpatialContainer.TYPE_VOLUME
    volume_container.extent = Vector3(0.6, 0.4, 0.6)  # 60cm x 40cm x 60cm
    if volume_container.request_container() != OK:
        push_error("Volume container request failed.")
        return

    # Panel container for the HUD.
    panel_container = SpatialContainer.new()
    panel_container.container_type = SpatialContainer.TYPE_PANEL
    panel_container.extent = Vector3(0.4, 0.4, 0.02)
    panel_container.request_container()

    add_child(volume_container)
    add_child(panel_container)

    container_created.emit(volume_container.get_container_handle())

func _process(_delta: float) -> void:
    # Containers can be rejected or resized by the system.
    if volume_container and not volume_container.is_active():
        _handle_container_loss()

func _handle_container_loss() -> void:
    push_warning("Volume container lost - repositioning.")
    # Never assume the container survives; re-request on loss.
    volume_container.request_container()

Ловушка, в которую попадают почти все: дрейф якоря

Вот конкретная проблема, и именно она отнимет у вас больше всего времени на отладку.

Вы размещаете 3D-доску в объёмном контейнере. Нажимаете Play. Всё выглядит правильно. Снимаете очки, надеваете через две минуты — доска теперь на полметра левее и повёрнута на 20 градусов.

Почему? Потому что вы привязали контент к началу мира (world origin), а не к контейнеру. Начало мира на пространственном устройстве — нестабильное место: оно определяется относительно позы начала сессии. Когда сессия повторно якорится, начало мира сдвигается.

Решение — держать каждый элемент сцены как потомка трансформа контейнера и никогда не читать и не писать глобальную позицию для пространственного контента:

# WRONG: assumes world origin is stable
func place_piece(piece: Node3D, board_pos: Vector3) -> void:
    piece.global_position = board_pos

# RIGHT: position relative to the container transform
func place_piece(piece: Node3D, board_pos: Vector3) -> void:
    piece.position = board_pos   # local to container
    piece.rotation = Vector3.ZERO

Перед релизом сделайте grep по проекту на .global_position и .global_transform. Каждое вхождение в пространственном контенте — потенциальный баг дрейфа. Этот класс багов встречается и в обычном 3D, и в мультиплеере — ошибки якоря и владения в реплицируемом трансформе дают тот же симптом «объект телепортировался для части клиентов». Поэтому привычка считать трансформы локальными относительно контейнера, а не абсолютными, полезна в любом сетевом Godot-проекте.

Проверка исправления

Чтобы убедиться, что якорение корректно:

  1. Запустите сцену и отметьте позицию доски.
  2. Снимите устройство, подождите 60 секунд, снова войдите в приложение.
  3. Доска должна появиться в том же физическом месте относительно комнаты, а не с тем же смещением относительно того, где вы стоите.
  4. Повторите с устройством в другой ориентации — сидя, затем стоя.

Если дрейфует — в дереве контента остались абсолютные ссылки. Если прыгает, но после прыжка остаётся стабильным — контейнер перемещается, а контент корректно следует за ним; это ожидаемое поведение, а не баг.

Управление идентичностью игрока и постоянным состоянием

Пространственные приложения на Android XR — это Android-приложения. Они приостанавливаются, возобновляются, у пользователя может быть несколько учётных записей на устройстве, а ваши сохранения живут в той же экосистеме аккаунтов, что и всё остальное.

Сценарий отказа тонкий: игрок играет в пространственном режиме на очках, затем открывает ту же игру на телефоне. Если состояние сохранения привязано к устройству, у него два расходящихся мира и нет способа их согласовать. Решение этой проблемы — не вопрос рендеринга, а вопрос идентификации аккаунта.

Чтобы сделать правильно самостоятельно, придётся реализовать вход в аккаунт, серверное хранилище сохранений и — то, что все недооценивают — обработку конфликтов, когда два устройства пишут в один слот сохранения. Модель чтения/записи с учётом ревизий, где клиент сравнивает версии и явно разрешает конфликты, — единственная, которая выдерживает контакт с реальными пользователями. Создание этого с нуля — работа на несколько недель; horizOn предоставляет облачные сохранения, привязанные к аккаунту, с чтением и записью с учётом ревизий — именно для этого случая, а также аутентификацию по email, анонимно, через Google и Apple, чтобы одна и та же идентичность игрока переносилась с очков на телефон.

Какой бы бэкенд вы ни использовали, определите политику конфликтов до релиза. «Последняя запись побеждает» молча уничтожает прогресс. Лучше спросить игрока, чем потерять данные.

Лучшие практики для релиза на XREAL AURA

  1. Проектируйте с учётом окружающего света. Тестируйте каждую UI-панель на улице в полдень и в тёмной комнате. Если текст становится нечитаемым в любом из условий, поднимите контраст и добавьте тонкую светлую обводку вместо тёмной тени — тени на прозрачном дисплее не работают.
  2. Держите контейнеры маленькими и повторно запрашиваемыми. Объём 60 см системе разместить надёжнее, чем 2 м. Исходите из того, что любой контейнер может быть потерян в любой момент, и пишите путь восстановления первым, а не последним.
  3. Жёстко ограничивайте бюджет рендеринга. Это очки, а не десктопный GPU. Держите время кадра ниже 11 мс (класс 90 Гц), отключите темпоральное сглаживание в пользу MSAA — при пространственных разрешениях оно дешевле.
  4. Размещайте UI в панелях, контент — в объёмах. Не боритесь с логикой размещения системы для текста. Оставьте объёмы для объектов с реальной глубиной, которые игрок рассматривает под разными углами.
  5. Проверяйте на устройстве перед каждой вехой. Редактор на очках делает это дёшево. Результаты симулятора не покажут дрейф якоря, проблемы с яркостью или поведение потери контейнера.

Делаем следующий шаг

Редактор на устройстве — вот настоящая главная новость. Он сжимает цикл пространственной итерации с минут до секунд, а это разница между доводкой дизайна и угадыванием.

Начните с установки редактора и сопутствующего Gradle-приложения на AURA, затем пересоберите небольшой существующий проект как пространственную сцену, а не начинайте с нуля — вы сразу увидите проблемы якорения и яркости на уже знакомом контенте. Дальше добавьте 3D-контейнер volume и UI-панель и добейтесь стабильности обоих при цикле приостановки/возобновления. Когда это заработает, вы готовы проектировать для платформы, а не против неё.

Если в вашем списке есть постоянное межплатформенное состояние игрока, horizOn обеспечивает облачные сохранения, привязанные к аккаунту, с разрешением конфликтов на стороне клиента, чтобы пространственная сессия и сессия на обычном экране оставались согласованными.


Источник: Готовы к XREAL AURA