Как использовать пространственные контейнеры в Godot

Поддерживаемые XR-устройства
Это руководство поможет вам создавать продукты для таких XR-устройств.
XR-шлемы
Проводные XR-очки

Пространственные контейнеры позволяют приложению отрисовывать 3D-контент OpenXR внутри управляемой системой 3D-ограничительной рамки в режиме полного пространства или переходить во время выполнения в полноэкранный режим без ограничений.

В этом руководстве рассказывается, как настроить и использовать пространственные контейнеры в проекте.

Несколько пространственных контейнеров, работающих в режиме полного пространства на Android XR.
Рисунок 1. Пространственные контейнеры в режиме полного пространства, включая контейнер с 3D-рельефом, привязанный к полу, и 3D-модель в паре с 2D-интерфейсом.

Как работают пространственные контейнеры

Если вы включите пространственный контейнер в настройках проекта:

  • Вся активная 3D-сцена помещается в один основной пространственный контейнер с центром в начале координат сцены (0, 0, 0). Вам не нужно помечать или назначать отдельные узлы Node3D, чтобы поместить их в контейнер.
  • Приложение запускается в управляемом режиме полного пространства с использованием режима границ (Bounded или Immersive) и начальных размеров границ, заданных в настройках проекта. В ограниченном режиме система автоматически обрезает любую трехмерную геометрию в сцене, которая выходит за пределы размеров ограничивающей рамки.
  • По умолчанию система Android XR предоставляет элементы управления окном, чтобы пользователь мог захватывать, перемещать и изменять положение ограниченного контейнера в трехмерном пространстве, а также сворачивать и закрывать его. Во время выполнения приложение может изменять размер контейнера, переключаться между ограниченным режимом (OpenXRSpatialContainerState.BOUNDED) и полноэкранным режимом погружения (OpenXRSpatialContainerState.IMMERSIVE), а также реагировать на изменения границ и состояния с помощью синглтона OpenXRSpatialContainerExtension.

Требования

Прежде чем начать, убедитесь, что ваша среда разработки и целевое устройство соответствуют следующим требованиям:

  • Версия Godot: Godot 4.8-dev или более поздняя.
  • Настройка проекта. Выполните все шаги, описанные в руководстве по настройке проекта Godot Engine.
  • Плагин Godot OpenXR Vendors. Установите плагин Godot OpenXR Vendors версии 5.2 или выше, чтобы включить поддержку расширений, предназначенных для Android XR.
  • Целевое устройство. Устройство Android XR, поддерживающее Spatial API уровня 4 или выше. Во время выполнения вызовите OpenXRSpatialContainerExtension.is_enabled(), чтобы проверить, доступно ли расширение на устройстве.

Включите пространственные контейнеры в настройках проекта.

Настройте проект, чтобы включить OpenXR, пространственные контейнеры, автоматические динамические разрешения и сквозную передачу с альфа-смешиванием:

  1. Выберите Project (Проект) > Project Settings (Настройки проекта).
  2. В правом верхнем углу окна Project Settings (Настройки проекта) включите параметр Advanced Settings (Расширенные настройки).
  3. Перейдите в раздел General (Общие) > XR > Shaders (Шейдеры) и выберите Enabled (Включено).
  4. Перейдите в раздел General > XR > OpenXR (Общие > XR > OpenXR) и задайте следующие настройки:
    • Выберите Enabled (Включено), чтобы включить OpenXR для проекта.
    • Для параметра Environment Blend Mode (Режим смешивания окружения) выберите значение Alpha Blend (Альфа-смешивание).
  5. В разделе OpenXR перейдите в раздел Extensions (Расширения) и задайте следующие настройки:
    • Выберите Automatically Request Runtime Permissions (Автоматически запрашивать динамические разрешения), чтобы при запуске приложения пользователю автоматически предлагалось предоставить все разрешения XR, указанные в манифесте Android.
    • В подразделе Пространственный контейнер выберите Включено.
    • В поле Bounds Mode (Режим границ) выберите Bounded (Ограниченный), чтобы запустить приложение в трехмерной граничной рамке, или Immersive (Режим погружения), чтобы запустить его в полноэкранном режиме погружения.
    • Задайте для параметра Bounds (Границы) исходные значения ширины, высоты и глубины в метрах, например Vector3(1.0, 1.0, 1.0).
  6. Перейдите в раздел General (Общие) > Rendering (Рендеринг) > Viewport (Область просмотра) и выберите Transparent Background (Прозрачный фон).

Как настроить экспорт, разрешения и полное пространство в Android

Затем настройте набор параметров экспорта для Android, разрешения и режим запуска действий, чтобы приложение работало в режиме полного пространства с включенными пространственными контейнерами.

Настройте пресет экспорта для Android

  1. Выберите Project > Export… (Проект > Экспорт…) и укажите набор настроек экспорта для Android.
  2. В разделе Gradle Build (Сборка Gradle) выберите Use Gradle Build (Использовать сборку Gradle) и задайте для параметра Min SDK (Минимальная версия SDK) значение 34 или выше.

    Включите

  3. В разделе XR Features (Функции XR) для параметра XR Mode (Режим XR) выберите значение OpenXR и установите флажок Enable AndroidXR Plugin (Включить плагин AndroidXR).

    Настройте параметры в разделе

  4. В разделе Функции Android XR выберите Использовать экспериментальные функции.

Добавьте разрешения на распознавание сцены для фиксации пола

Для создания и рендеринга базового пространственного контейнера не требуются опасные динамические разрешения (а android.permission.HEAD_TRACKING добавляется в манифест автоматически, когда включен параметр Использовать экспериментальные функции). Однако если в приложении используются функции распознавания сцены, например закрепление и привязка пространственного контейнера к физическому полу, то в приложении необходимо объявить и запросить разрешение android.permission.SCENE_UNDERSTANDING_COARSE во время выполнения.

Подробнее о разрешениях для Android XR… Если в вашем приложении используется фиксация пола или распознавание сцены, объявите и запросите разрешение android.permission.SCENE_UNDERSTANDING_COARSE.

  1. В меню Project (Проект) > Export (Экспорт) > Android, перейдите в раздел Permissions (Разрешения) > Custom Permissions (Специальные разрешения) и добавьте android.permission.SCENE_UNDERSTANDING_COARSE.

  2. Если вы выберете Automatically Request Runtime Permissions (Автоматически запрашивать динамические разрешения) в разделе Project Settings (Настройки проекта) > General (Общие) > XR > OpenXR > Extensions (Расширения), ваше приложение будет автоматически запрашивать разрешение при запуске OpenXR. Если вам нужно запросить разрешение вручную в GDScript, вызовите OS.request_permission():

    if not OS.get_granted_permissions().has("android.permission.SCENE_UNDERSTANDING_COARSE"):
        OS.request_permission("android.permission.SCENE_UNDERSTANDING_COARSE")
    

Настроить режим полного пространства

Пространственные контейнеры в Android XR поддерживают только режим полного пространства (XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED). Убедитесь, что в шаблоне сборки (android/build/AndroidManifest.xml, устанавливается через Project > Install Android Build Template… (Проект > Установить шаблон сборки Android…)) для действия Android указано XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED.

<manifest ...>
    <application ...>
        <property
            android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE"
            android:value="XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED"
            tools:replace="android:value" />
        ...
    </application>
</manifest>

Работа с пространственными контейнерами в GDScript

Синглтон OpenXRSpatialContainerExtension и класс OpenXRSpatialContainerState предоставляют расширения XR_EXT_spatial_container и XR_EXT_spatial_container_self_rendering для GDScript. Во время выполнения используйте OpenXRSpatialContainerExtension, чтобы проверить состояние и границы основного пространственного контейнера, прослушать сигналы контейнера и запросить переходы между режимом BOUNDED (трехмерная ограничивающая рамка) и полноэкранным режимом IMMERSIVE (неограниченный вид).

Подключение к сигналам Spatial Container

Проверьте OpenXRSpatialContainerExtension.is_enabled(), чтобы убедиться, что расширение Spatial Container поддерживается и активно на текущем устройстве, и подключитесь к сигналам границ и состояния контейнера в _ready().

OpenXRSpatialContainerExtension передает следующие сигналы состояния для пространственного контейнера:

  • spatial_container_visibility_changed – отправляется с (spatial_container, is_visible), когда контейнер показывается (true) или скрывается (false). Приостанавливайте анимацию, аудио или обновления симуляции, когда is_visible имеет значение false.
  • spatial_container_interactability_changed: отправляется с (spatial_container, is_interactive), когда контейнер получает (true) или теряет (false) фокус ввода пользователя. Включить или отключить интерактивную подсветку и обработку ввода при изменении фокуса.
  • spatial_container_bounds_mode_changed – передается с (spatial_container, bounds_mode), когда контейнер переключается между OpenXRSpatialContainerState.BOUNDED и OpenXRSpatialContainerState.IMMERSIVE. Переключайте визуальные эффекты окружения (например, скайбоксы или сквозной режим) и элементы управления пользовательского интерфейса для конкретного режима.
func _ready() -> void:
    if OpenXRSpatialContainerExtension.is_enabled():
        OpenXRSpatialContainerExtension.spatial_container_bounds_changed.connect(
            _on_bounds_changed
        )
        OpenXRSpatialContainerExtension.spatial_container_bounds_mode_changed.connect(
            _on_bounds_mode_changed
        )
        OpenXRSpatialContainerExtension.spatial_container_visibility_changed.connect(
            _on_visibility_changed
        )
        OpenXRSpatialContainerExtension.spatial_container_interactability_changed.connect(
            _on_interactability_changed
        )

func _on_visibility_changed(_rid: RID, is_visible: bool) -> void:
    # Pause or resume simulation and audio based on visibility
    pass

func _on_interactability_changed(_rid: RID, is_interactive: bool) -> void:
    # Enable or disable input handling and focus highlights
    pass

Масштабировать 3D-контент по границам контейнера

В режиме BOUNDED масштабируйте 3D-контент равномерно по наименьшему размеру bounds, чтобы сохранить соотношение сторон и всегда помещать его в наименьшую сторону контейнера. При переходе в режим IMMERSIVE восстановите масштаб сцены 1:1.

func _on_bounds_changed(_rid: RID, bounds: Vector3) -> void:
    var uniform_scale: float = min(bounds.x, bounds.y, bounds.z)
    content_root.scale = Vector3.ONE * uniform_scale

func _on_bounds_mode_changed(
    _rid: RID, bounds_mode: OpenXRSpatialContainerState.BoundsMode
) -> void:
    if bounds_mode == OpenXRSpatialContainerState.IMMERSIVE:
        content_root.scale = Vector3.ONE

Переключение между ограниченным режимом и режимом погружения

Вызовите request_main_spatial_container_bounds_mode с помощью OpenXRSpatialContainerState.BOUNDED или OpenXRSpatialContainerState.IMMERSIVE, чтобы переключиться между ограниченным трехмерным объемом и полноэкранным иммерсивным режимом:

# Request transitioning to immersive mode (or pass BOUNDED to return)
OpenXRSpatialContainerExtension.request_main_spatial_container_bounds_mode(
    OpenXRSpatialContainerState.IMMERSIVE
)

Дополнительная информация


OpenXR™ и логотип OpenXR являются товарными знаками, принадлежащими The Khronos Group Inc. и зарегистрированными в Великобритании, Европейском союзе, Китае и Японии.