Как добавить поддержку Android XR в существующий проект Godot XR

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

Если у вас уже есть проект XR в Godot, вы можете добавить поддержку Android XR, не создавая новый проект. Некоторые шаги обязательны для всех проектов, а другие – необязательны и зависят от функций XR, которые используются в вашем проекте. В инструкциях есть ссылки на несколько проектов Godot XR с открытым исходным кодом, в которых добавлена поддержка Android XR, а также на pull-запросы, показывающие, какие изменения нужны для включения определенных функций.

Обязательные действия для всех проектов

Выполните действия, описанные в следующих разделах, независимо от того, какие типы функций XR поддерживает ваш проект. Затем ознакомьтесь со списком необязательных шагов, чтобы определить, нужно ли вам выполнить дополнительные действия.

Обновите Godot и плагин Godot OpenXR Vendors

Чтобы обновить проект до последних требуемых версий и настроить его для Android XR, выполните следующие действия:

  1. Обновите Godot до версии 4.6.2 или более поздней. Если вам нужна дополнительная помощь, ознакомьтесь с документацией по переходу на новую версию.
  2. Скачайте плагин Godot OpenXR Vendors версии 5.1 или более поздней из магазина объектов, библиотеки объектов или хранилища на GitHub.

  3. Задайте настройки проекта для Android XR:

    1. Добавьте набор настроек экспорта для Android XR.
    2. Включите параметр Use Gradle Build (Использовать сборку Gradle).

    Включите

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

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

Добавьте поддержку отслеживания рук

Хотя контроллеры могут быть доступны, основным методом ввода на XR-шлемах и XR-очках Android XR является отслеживание рук. Если возможно, добавьте в проект Godot поддержку отслеживания рук.

Как добавить поддержку отслеживания рук: настройте проект

Сначала включите отслеживание рук и связанные с ним расширения OpenXR в настройках проекта.

  1. Откройте настройки проекта и перейдите в раздел General > XR > OpenXR (Общие > XR > OpenXR).
  2. В разделе Extensions (Расширения) выберите Hand Tracking (Отслеживание рук) и Hand Interaction Profile (Профиль взаимодействия рук).

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

  3. В разделе Extensions (Расширения) найдите подраздел Meta и выберите Hand Tracking Mesh (Сетка отслеживания рук) и Hand Tracking Aim (Цель отслеживания рук).

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

Как добавить поддержку отслеживания рук: добавьте и настройте узлы контроллера

Вместо того чтобы динамически изменять существующие узлы XRController3D для отслеживания рук, добавьте узлы контроллера для отслеживания и отображения моделей рук, а также для обработки входных данных из расширения Hand Tracking Aim:

  1. Добавьте ещё три узла XRController3D к узлу XROrigin3D.

    1. Назовите один из них HandTrackingLeft и задайте для свойства tracker значение /user/hand_tracker/left.
    2. Назовите другой HandTrackingRight и задайте для свойства трекера значение /user/hand_tracker/right.
    3. Последний назовите HandTrackingAimLeft и задайте для свойства Tracker значение /user/fbhandaim/left.

    Если исходные узлы XRController3D вашего проекта назывались XRController3D_left и XRController3D_right, сцена будет выглядеть примерно так:

    Вот как может выглядеть сцена после добавления узлов контроллера.

  2. Подключите сигнал tracking_changed в HandTrackingLeft и HandTrackingRight к отдельным функциям, которые обновляют видимость соответствующих трекеров контроллеров (XRController3D_left и XRController3D_right в примере выше).

    Например, функция, подключенная к сигналу на HandTrackingLeft, может выглядеть так:

    func _on_hand_tracking_left_hand_tracking_changed(tracking):
        $XROrigin3D/XRController3D_left.visible = not tracking
    
  3. Включите свойство Show When Tracked (Показывать при отслеживании) на узлах контроллера отслеживания рук.

    Теперь в вашем проекте можно визуально переключаться между моделями контроллеров и моделями отслеживания рук в зависимости от того, использует ли пользователь отслеживание рук или контроллеры.

  4. Добавьте несколько узлов OpenXRFbHandTrackingMesh в качестве дочерних к узлам контроллера отслеживания рук.

  5. Добавьте узлы XRHandModifier3D в качестве дочерних к узлам OpenXRFbHandTrackingMesh, убедившись, что задано правильное свойство Hand Tracker, чтобы применить к моделям данные отслеживания рук в реальном времени.

    Вот как может выглядеть сцена после добавления дочерних узлов к узлам контроллера.

Добавьте поддержку отслеживания рук: настройте профиль Hand Interaction на карте действий OpenXR.

Теперь настройте профиль Hand Interaction (Взаимодействие с помощью рук) в OpenXR Action Map (Карта действий OpenXR):

  1. Откройте меню OpenXR Action Map (Карта действий OpenXR) в нижней части редактора.
  2. Удалите профиль Simple Controller, чтобы избежать проблем с совместимостью с контроллерами Galaxy XR.
  3. Нажмите Add Profile (Добавить профиль), выберите Hand Interaction (Взаимодействие с помощью рук) и нажмите OK.
  4. Сопоставьте этот профиль с одним или несколькими наборами действий.

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

Как добавить поддержку отслеживания рук: настройте жест для открытия меню в Android XR

Наконец, вы можете реализовать жест для открытия меню в Android XR. Это показывает значок, когда левая рука игрока находится в правильном положении для выполнения жеста меню, а также показывает или скрывает меню, когда пользователь выполняет жест. Для этого используйте узел HandTrackingAimLeft, который вы добавили ранее.

  1. Добавьте к узлу отслеживания рук левой руки рекламный щит с выбранным вами значком (см. узел MenuIcon на изображении ниже).

    Вот как может выглядеть сцена после добавления дочерних узлов к узлам контроллера.

  2. Подключитесь к сигналам button_pressed и button_released в HandTrackingAimLeft, чтобы использовать такие функции:

    @onready var menu_icon: MeshInstance3D = $XROrigin3D/HandTrackingLeft/MenuIcon
    
    func _on_hand_tracking_aim_left_button_pressed(p_name):
      if p_name == "menu_pressed":
    toggle_menu()
      elif p_name == "menu_gesture":
        if OS.has_feature("androidxr"):
          menu_icon.visible = true
    
    func _on_hand_tracking_aim_left_button_released(p_name):
      if p_name == "menu_gesture":
        menu_icon.visible = false
    

Необязательные шаги для некоторых функций

Выполнив необходимые действия для своего проекта, вы решаете, нужно ли вам выполнять дополнительную работу для определенных функций, в зависимости от требований и возможностей вашего приложения. Подробная информация о каждой из этих дополнительных функций приведена в разделах ниже.

Регистрация сведения пальцев как нажатия кнопки

В Android XR сведение пальцев используется для многих основных системных действий, таких как выбор элементов, прокрутка, перемещение или изменение размера окон, а также перемещение элементов пользовательского интерфейса или объектов в 2D- и 3D-пространстве. Чтобы соответствовать этим шаблонам и обеспечить единообразие пользовательского опыта, ваше приложение должно регистрировать щипки аналогично нажатиям кнопок на контроллере при использовании отслеживания рук.

Чтобы настроить приложение таким образом, используйте значения с плавающей запятой, предоставляемые созданным вами профилем взаимодействия рук, чтобы создать виртуальное действие:

const PRESSED_THRESHOLD := 0.8
const RELEASED_THRESHOLD := 0.6

@onready var left_controller: XRController3D = $XROrigin/XRController3D_left

func _on_xr_controller_3d_left_input_float_changed(p_name: String, value: float):
    if p_name == "pinch":
        var xr_tracker = XRServer.get_tracker(left_controller.tracker)
        if _left_hand_pinching:
            if value < RELEASED_THRESHOLD:
                _left_hand_pinching = false
                xr_tracker.set_input("pinch_pressed", false)
        else:
            if value > PRESSED_THRESHOLD:
                _left_hand_pinching = true
                xr_tracker.set_input("pinch_pressed", true)

Важные сведения о коде

  • Проверяет, превышает ли значение float определенные пороговые значения в сигналах input_float_changed XRController3D или не достигает их.
  • Создает виртуальное действие pinch_pressed.

Как использовать функции XR Tools вместе с отслеживанием рук

Во многих проектах Godot XR используются инструменты Godot XR, в том числе в некоторых проектах с открытым исходным кодом, ссылки на которые приведены на этой странице. Чтобы некоторые функции XR Tools работали, например FunctionPointer для взаимодействия с меню, вам понадобится дополнительный код, который будет менять действие, когда пользователь переключается на отслеживание рук.

Например, если вы используете FunctionPointer для взаимодействия с меню, обновите свойство active_button_action, чтобы оно соответствовало действию отслеживания рук на основе сигнала tracking_changed узлов XRController3D для отслеживания рук (в инструкциях по настройке отслеживания рук выше это узлы HandTrackingLeft и HandTrackingRight).

const TRIGGER_POINTER_ACTION = "trigger_click"
const PINCH_POINTER_ACTION = "pinch_pressed"

@onready var func_point_left: XRToolsFunctionPointer = %FunctionPointerLeft

func _on_hand_tracking_left_tracking_changed(tracking: bool) -> void:
    if tracking:
        func_point_left.active_button_action = PINCH_POINTER_ACTION
else:
func_point_left.active_button_action = TRIGGER_POINTER_ACTION

Важные сведения о коде

Используйте отслеживание рук вместе с искусственным перемещением

Если в вашем проекте используется искусственное перемещение, поддержка отслеживания рук все равно возможна. Например, вы можете создать систему перемещения, которая позволяет игрокам рисовать пути для перемещения с помощью жеста, или вы можете позволить игрокам поднимать и опускать руки для ускорения, используя дополнительные жесты для прыжков, лазания и скольжения.

В The Museum of All Things используется искусственное перемещение с помощью мини-джойстиков на контроллерах. Для перемещения в пространстве с помощью отслеживания рук были добавлены виртуальные мини-джойстики. Чтобы активировать их, игроку нужно свести два пальца вместе в воздухе и переместить руку в направлении, в котором должен двигаться мини-джойстик.

Вот некоторые ключевые выводы из pull-запроса, который реализовал эту поддержку:

  • При обнаружении сведения пальцев создается экземпляр сцены XRVirtualThumbstick.
  • Пока вы удерживаете щипок, относительное расстояние и направление от исходного местоположения щипка преобразуются в Vector2 и виртуально сопоставляются с обычным вводом с помощью мини-джойстика.
  • Визуальная обратная связь для этих входных данных также предоставляется игроку в виде двух сеток четырехугольников, иллюстрирующих положение джойстика.

Вы можете использовать аналогичный подход, чтобы заставить существующий код перемещения, управляемый мини-джойстиком, работать с минимальными изменениями. Однако для вашего проекта все равно может потребоваться специальное решение для перемещения с отслеживанием рук.

Добавьте поддержку сквозной передачи

Вы можете добавить в приложение поддержку сквозной камеры, чтобы пользователи видели, что происходит вокруг них.

Для этого внесите в код приложения следующие изменения:

  • Задайте для свойства environment_blend_mode объекта XRInterface OpenXR значение XR_ENV_BLEND_MODE_ALPHA_BLEND.
  • Задайте для атрибута background_mode узла WorldEnvironment значение BG_COLOR.
  • Задайте для узла WorldEnvironment значение background_color, соответствующее полностью прозрачному цвету.
  • Задайте для свойства Viewport transparent_bg значение true.

Как использовать расширение для оценки освещенности

При включении сквозного режима рекомендуем использовать расширение Android XR Light Estimation OpenXR. Это расширение настраивает свойства WorldEnvironment и DirectionalLight3D, чтобы лучше имитировать освещение реального мира пользователя. В результате виртуальные объекты лучше вписываются в реальные условия освещения. Вы можете включить это расширение в настройках проекта.

  1. Откройте настройки проекта и перейдите в раздел General > XR > OpenXR (Общие > XR > OpenXR).
  2. В разделе Androidxr выберите Light Estimation (Оценка освещенности).

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

  3. Добавьте узел OpenXRAndroidLightEstimation в дерево сцены и подключите его к WorldEnvironment и DirectionalLight3D сцены.

    Параметры для

Пример. Как включить или отключить сквозной режим и оценку освещенности

Следующий код включает или отключает сквозной режим и оценку освещенности:

@onready var world_environment = $WorldEnvironment
@onready var directional_light = $DirectionalLight3D
@onready var directional_light_orig_transform: Transform3D = directional_light.transform

func set_passthrough_enabled(p_enabled: bool) -> void:
    var xr_interface = XRServer.find_interface("OpenXR")
    if xr_interface == null:
        return

    var supported_blend_modes = xr_interface.get_supported_environment_blend_modes()
    if not supported_blend_modes.has(XRInterface.XR_ENV_BLEND_MODE_ALPHA_BLEND):
        return

    # Passthrough
    if p_enabled:
        xr_interface.set_play_area_mode(XRInterface.XR_PLAY_AREA_STAGE)
        xr_interface.environment_blend_mode = XRInterface.XR_ENV_BLEND_MODE_ALPHA_BLEND
        world_environment.environment.background_mode = Environment.BG_COLOR
        world_environment.environment.background_color = Color(0.0, 0.0, 0.0, 0.0)
        get_viewport().transparent_bg = true
    else:
        xr_interface.set_play_area_mode(XRInterface.XR_PLAY_AREA_ROOMSCALE)
        xr_interface.environment_blend_mode = XRInterface.XR_ENV_BLEND_MODE_OPAQUE
        world_environment.environment.background_mode = Environment.BG_SKY
        get_viewport().transparent_bg = false

    # Light Estimation
    if OS.has_feature("androidxr"):
        var light_estimation = Engine.get_singleton("OpenXRAndroidLightEstimationExtension")
        if p_enabled and light_estimation.is_light_estimation_supported():
            light_estimation.start_light_estimation()
        elif light_estimation.is_light_estimation_started():
            light_estimation.stop_light_estimation()
            directional_light.transform = directional_light_orig_transform
Важные сведения о коде
  • При отключении оценки освещенности исходное направление DirectionalLight3D необходимо восстановить вручную.
  • Полный пример проекта, в котором используется сквозная камера и оценка освещенности, можно найти в Expedition to Blobotopia на GitLab.