為現有的 Godot XR 專案新增 Android XR 支援

適用的 XR 裝置
這份指南可協助您為這類 XR 裝置打造體驗。
XR 頭戴式裝置
有線 XR 眼鏡

如果您在 Godot 中已有 XR 專案,可以新增 Android XR 支援,不必另外建立新專案。部分步驟是所有專案的必要步驟,其他步驟則視專案使用的 XR 功能而定。在各個步驟中,我們都加入了多個開放原始碼 Godot XR 專案的連結,這些專案已新增 Android XR 支援功能,以及相關的提取要求,展示啟用特定功能所需的變更。

所有專案都必須完成的步驟

無論專案支援哪種延展實境功能,都請完成下列主題中的步驟。接著,請查看選用步驟清單中列出的功能,判斷專案是否需要額外作業。

更新 Godot 和 Godot OpenXR 供應商外掛程式

請按照下列步驟將專案更新至最新必要版本,並為 Android XR 設定專案設定:

  1. 將 Godot 版本更新至 4.6.2 以上。如需專案的額外協助,請參閱遷移至新版本的說明文件。
  2. Asset StoreAsset LibraryGitHub 存放區下載 Godot OpenXR Vendors Plugin 5.1 以上版本。

  3. 設定 Android XR 專案設定:

    1. 新增 Android XR 的匯出預設設定。
    2. 啟用「使用 Gradle 建構」

    啟用

    1. 在「XR Features」部分,選取「XR Mode」的「OpenXR」,然後選取「Enable AndroidXR Plugin」

    在

新增手勢追蹤支援

Android XR 頭戴式裝置和 XR 眼鏡可能支援控制器,但主要輸入方式是手勢追蹤。如有可能,請在 Godot 專案中加入手部追蹤支援功能。

新增手勢追蹤支援功能:設定專案設定

請先按照下列步驟設定專案,啟用手部追蹤功能和相關的 OpenXR 擴充功能。

  1. 開啟專案設定,然後依序前往「General」>「XR」>「OpenXR」
  2. 在「擴充功能」部分,選取「手部追蹤」和「手部互動設定檔」

    在

  3. 在「擴充功能」專區中找到「Meta」子專區,然後選取「手勢追蹤網格」和「手勢追蹤瞄準」

    在

新增手勢追蹤支援功能:新增及設定控制器節點

請勿動態修改現有的 XRController3D 節點以追蹤手部,而是新增控制器節點,追蹤及顯示手部模型,並處理手部追蹤瞄準擴充功能的輸入內容:

  1. XROrigin3D 節點中新增三個 XRController3D 節點。

    1. 將其中一個命名為「HandTrackingLeft」,並將追蹤器屬性設為 /user/hand_tracker/left
    2. 將另一個「HandTrackingRight」命名,並將追蹤器屬性設為 /user/hand_tracker/right
    3. 將最後一個命名為「HandTrackingAimLeft」,並將追蹤器屬性設為 /user/fbhandaim/left

    如果專案的原始 XRController3D 節點名為「XRController3D_left」和「XRController3D_right」,場景看起來會像這樣:

    新增控制器節點後,場景可能如下所示。

  2. tracking_changed 訊號連線至 HandTrackingLeftHandTrackingRight 上的個別函式,更新對應控制器追蹤器的顯示狀態 (前一個範例中的 XRController3D_leftXRController3D_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屬性,以便將即時手勢追蹤資料套用至模型。

    將子節點新增至控制器節點後,場景可能如下所示。

新增手勢追蹤支援:在 OpenXR 動作對應中設定手部互動設定檔

接著,您會在 OpenXR 動作對應中設定「手部互動」設定檔:

  1. 開啟編輯器底部的「OpenXR Action Map」選單。
  2. 刪除「Simple Controller」設定檔,避免與 Galaxy XR 控制器發生相容性問題。
  3. 按一下「新增設定檔」,選取「手部互動」,然後按一下「確定」
  4. 隨意將這個設定檔對應至一或多個動作集。

視應用程式需求而定,您可能也想調整應用程式如何透過手勢追蹤處理使用者輸入內容

新增手勢追蹤支援:設定 Android XR 的選單手勢

最後,您可以為 Android XR 實作選單手勢。當玩家的左手處於可執行選單手勢的正確位置時,系統會顯示圖示,並在使用者執行手勢時顯示或隱藏選單。您將使用先前新增的 HandTrackingAimLeft 節點處理這項作業。

  1. 在左側手勢追蹤節點中新增廣告看板四邊形,顯示您選擇的圖示 (請參閱下圖中先前新增的控制器節點中的 MenuIcon 節點)。

    將子節點新增至控制器節點後,場景可能如下所示。

  2. HandTrackingAimLeft 上的 button_pressedbutton_released 訊號連結至這類函式:

    @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 空間中移動 UI 元素或物件。為配合這些模式並提供一致的使用者體驗,使用手勢追蹤功能時,應用程式應以類似於控制器按鈕按壓的方式註冊捏合動作。

如要以這種方式設定應用程式,請使用您建立的「手部互動」設定檔提供的浮點值,建立虛擬動作:

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 值是否大於或小於 XRController3D input_float_changed 信號中的特定門檻。
  • 建立名為 pinch_pressed 的虛擬動作。

搭配手勢追蹤功能使用 XR Tools 函式

許多 Godot XR 專案都會使用 Godot XR Tools,包括這個頁面中連結的部分開放原始碼專案。如要讓部分 XR 工具函式 (例如選單互動的 FunctionPointer) 運作,您需要一些額外程式碼,在使用者切換至手勢追蹤時,交換要尋找的動作。

舉例來說,使用 FunctionPointer 進行選單互動時,請根據手勢追蹤的 XRController3D 節點 tracking_changed 信號,將 active_button_action 屬性更新為手勢追蹤動作 (在先前的手勢追蹤設定步驟中,這些節點為 HandTrackingLeftHandTrackingRight)。

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

程式碼重點

搭配人工移動功能使用手勢追蹤功能

如果專案使用人工移動,仍可支援手勢追蹤。舉例來說,您可以建立移動系統,讓玩家透過手勢繪製路徑來移動,也可以讓玩家上下擺動雙手來加速,並使用其他手勢跳躍、攀爬和滑翔。

萬物博物館:使用控制器上的拇指桿進行人工移動。手勢追蹤移動功能是透過新增「虛擬搖桿」實作,玩家只要在空中捏合手指即可觸發,並將手移往搖桿要移動的方向。

以下是實作這項支援功能的提取要求的一些重要事項:

  • 偵測到雙指撥動時,系統會例項化 XRVirtualThumbstick 場景。
  • 按住雙指時,系統會將與原始雙指位置的相對距離和方向轉換為 Vector2,並虛擬對應至一般搖桿輸入。
  • 系統也會以兩個廣告牌四邊形網格的形式,向玩家提供這項輸入內容的視覺回饋,說明搖桿位置。

您可以嘗試類似方法,盡可能減少變更,讓現有的搖桿驅動移動程式碼正常運作。不過,您的專案可能仍需要自訂手勢追蹤的移動解決方案。

新增直通支援

您可以在應用程式中加入透視支援,讓使用者看到現實世界周遭環境。

如要為應用程式執行這項操作,請進行下列程式碼變更:

  • 將 OpenXR XRInterfaceenvironment_blend_mode 設為 XR_ENV_BLEND_MODE_ALPHA_BLEND
  • WorldEnvironment 節點的 background_mode 設為 BG_COLOR
  • WorldEnvironment 節點的 background_color 設為完全透明的顏色。
  • Viewport transparent_bg 屬性設為 true

使用光線估計擴充功能

啟用透視功能時,請考慮使用 Android XR Light Estimation OpenXR 擴充功能。這項擴充功能會調整 WorldEnvironmentDirectionalLight3D 的屬性,更貼近使用者現實環境的光線,讓虛擬物體更融入現實世界的光線條件。您可以在專案設定中啟用這項擴充功能。

  1. 開啟專案設定,然後依序前往「General」>「XR」>「OpenXR」
  2. 在「Androidxr」部分中,選取「Light Estimation」

    在

  3. 在場景樹狀結構中新增 OpenXRAndroidLightEstimation 節點,並將其連結至場景的 WorldEnvironmentDirectionalLight3D

    「

示例:啟用或停用穿透和光線估算功能

下列程式碼會啟用或停用直通和光線估算功能:

@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 的原始方向。
  • 如需使用 Passthrough 和光線估算功能的完整專案範例,請參閱 GitLab 上的 Expedition to Blobotopia