XR 動作對應

Godot 的 XR 系統中包含動作對應功能。目前此系統屬於 OpenXR 模組。未來預計也會納入 WebXR,因此本文件統稱為 XR 動作對應系統。它幾乎完全依照 OpenXR 內建的動作對應系統實作。

XR 動作對應系統會將 XR 控制器的輸入、空間定位資料與輸出公開給您的遊戲/應用程式。其原理是公開可自訂的命名動作,並將這些動作綁定到 XR 裝置上的實際輸入與輸出。

由於 XR 動作對應目前屬於 OpenXR 模組,因此必須於專案設定中啟用 OpenXR 才能使用本功能:

../../_images/openxr_settings.webp

接著您會在畫面下方看到 XR 動作對應介面:

../../_images/xr_action_map.webp

備註

Godot 的內建輸入系統與 XR 動作對應系統有許多共通之處。最初我們原本打算直接在既有輸入系統上增擴功能,並將資料公開給 OpenXR 動作對應系統。雖然這想法不排除未來重啟,但實際上障礙不少,例如:

  • Godot 的輸入系統主要以按鍵輸入為核心,而 XR 則增加了扳機、軸向、姿勢與觸覺(輸出)等概念。這會讓輸入系統變得過於複雜,且許多功能不適用於一般手把或會與現有設計衝突,進而造成多數 Godot 使用者困惑。

  • Godot 的輸入系統是以原始資料為基礎,經解析後觸發動作,並將此類資料直接提供給用戶端。而 OpenXR 則完全隱藏原始資料,所有解析都內部完成,僅提供已處理好的動作資料。這樣的不一致,若開發者誤把 XR 裝置當作一般輸入裝置使用,容易發生錯誤。

  • Godot 的輸入系統允許在執行時動態更換輸入對應的動作,但 OpenXR 不支援。

  • Godot 的輸入系統以裝置 ID 區分來源,但在 OpenXR 中並無此意義。

這也意味著同時支援傳統輸入與 XR 控制器的遊戲/應用程式,這兩者會被系統分開處理。對大多數應用來說只需選用其中一種,並不成問題。歸根究柢,這是系統的設計限制。

預設動作對應

若專案未偵測到動作對應檔,Godot 會自動建立一份預設動作對應。

警告

這份預設對應是為協助開發者將 XR 遊戲/應用從 Godot 3 移植到 Godot 4 而設計。它基本上將所有已知的預設控制器輸入一對一綁定到動作上。這並非良好的對應設計範例,但對初學者來說可直接上手 Godot XR,無須先行設計專屬動作對應。

本教學將從一張空白的動作對應開始。可點選頂端的垃圾桶圖示刪除「Godot 操作集」條目,這會清空所有動作。你也可以移除不需要設定的控制器,後續會再說明。

動作集

備註

在開始之前,你會多次看到「XR 執行環境」這個詞。這裡指的是負責控制與管理 AR/VR 頭戴裝置的軟體,並透過像 OpenXR 這類 API 對外提供服務。舉例來說:

  • Steam 平台即為 SteamVR,

  • 桌面端的 Meta 是 Oculus Client(包含使用 Quest Link 時),

  • Quest 上的 Meta 則是 Quest 原生 OpenXR 客戶端,

  • 在 Linux 上則可能是 Monado 等。

動作對應可以將動作分組為多個動作集,每組皆可獨立啟用或停用。

可根據不同情境設計多組動作集,例如:

  • 「角色控制」動作集,對應玩家自由移動時,

  • 「載具控制」動作集,對應駕駛載具時,

  • 「選單」動作集,對應開啟遊戲選單時。

每次僅啟用適用於遊戲/應用目前狀態的動作集。

若需要將同一控制器的同一輸入綁定到不同動作時,這特別重要。例如:

  • 「角色控制」動作集中可能有「跳躍」動作,

  • 「載具控制」動作集中可能有「加速」動作,

  • 「選單」動作集中可能有「選擇」動作。

以上動作都綁定到你控制器的扳機鍵。

OpenXR 一次僅允許將某個輸入或輸出綁定到單一動作。如果多個動作集同時啟用且都有綁定同一輸入/輸出,會以優先權最高的動作集為主。故如上述範例,務必確保僅啟用一組動作集。

建議您的第一個 XR 專案僅設計一組動作集,避免過度設計。

本教學將建立一組名為 my_first_action_set 的動作集,請點選「新增動作集」按鈕:

../../_images/xr_my_first_action_set.webp

表格中的欄位意義如下:

欄位

說明

1

my_first_action_set

這是動作集的內部名稱。OpenXR 僅限制名稱長度,部分 XR 執行環境不接受空白或特殊字元。

2

我的第一組動作集

這是人類可讀的動作集名稱。部分 XR 執行環境會在設定介面等地方顯示此名稱給使用者。

3

0

這是動作集的優先權。若多組動作集同時啟用且綁定相同控制器輸入/輸出,則優先權最高者會決定啟用哪個動作。

動作

在 XR 動作對應中,「動作」代表遊戲/應用程式可互動的行為。例如你可定義一個動作 Shoot,當對應輸入啟動時,將觸發場景中 XRController3D 節點的 button_pressed 訊號,參數 name 會是 Shoot

你也可以主動查詢動作目前狀態,例如 XRController3D 節點中有 is_button_pressed 方法。

動作可對應輸入或輸出,每個動作有其型別,決定其行為。

  • Bool 型別用於離散輸入(如按鍵)。

  • Float 型別用於類比輸入(如扳機)。

這兩種型別可互換,OpenXR 會自動在 BoolFloat 之間做轉換。你可透過 XRController3D 節點的 get_float 取得 Float 型別動作的數值,且當數值變動時會觸發 input_float_changed 訊號。

備註

當以按鍵方式查詢類比輸入時,會套用閾值。該閾值目前完全由 XR 執行環境管理,未來 Godot 預計將開放部分調整權限。

Vector2 型別用於軸向輸入。例如觸控板、搖桿等會以向量輸出。你可經由 XRController3D 節點的 get_vector2 取得值,數值變動時會發送 input_vector2_changed 訊號。

Pose 型別表示空間追蹤輸入。OpenXR 支援多種「姿勢」輸入:如 aimgrippalm。你的 XRController3D 節點會依照 pose 屬性綁定的動作自動定位。

備註

Godot 的 OpenXR 實作也提供名為 Skeleton 的特殊姿勢,用於手部追蹤。這個姿勢會由動作對應系統之外的 skeleton 動作自動提供,只要支援手部追蹤就會存在,無需另外綁定動作即可使用。

最後,唯一的輸出型別是 Haptic,可設定觸覺回饋強度(如控制器震動)。控制器可有多組觸覺輸出,OpenXR 也即將支援觸覺背心等裝置。

現在我們來為瞄準姿勢新增動作。請在動作集下方點選「+」按鈕:

../../_images/xr_aim_pose.webp

表格中的欄位意義如下:

欄位

說明

1

aim_pose

這是動作的內部名稱,OpenXR 僅限制長度,部分 XR 執行環境不接受空白或特殊符號。

2

瞄準姿勢

這是動作的顯示名稱,部分 XR 執行環境會於設定等介面顯示給使用者。

3

姿勢

此動作的型別。

OpenXR 規範多種可綁定的輸入姿勢,實際支援的姿勢因控制器而異,目前 OpenXR 定義的有:

  • 大多數控制器的 aim 姿勢會對應到控制器前方微距位置,並朝向正前方。這很適合用於雷射指標或武器槍口等對準應用。

  • 大多數控制器的 grip 姿勢對應控制器握把按鈕處。不同控制器、甚至同型號於不同 XR 執行環境下方向可能會不同。

  • 大多數控制器的 palm 姿勢對應手掌心握住控制器的位置。此為較新姿勢,並非所有 XR 執行環境皆支援。

備註

如需手部追蹤,目前各家 XR 執行環境實作差異極大,因此動作對應暫不適合用於手部追蹤。相關改進正在推進中,請持續關注。

以下列舉一個簡單射擊遊戲/應用程式的動作清單:

../../_images/xr_all_actions.webp

我們新增的動作有:

  • movement:讓玩家能在房間規模追蹤以外移動。

  • grab:偵測玩家想抓取物件。

  • shoot:偵測玩家想開槍。

  • haptic:輸出觸覺回饋。

請注意,這裡我們尚未區分左右手。實際上,動作系統允許同一動作同時綁定於雙手,之後再決定左右手分工。對應的 XRController3D 節點會自動發出訊號。

警告

grab 與 shoot 動作都用 Bool 型別。雖然 OpenXR 會自動將類比控制轉為 Bool,但不是所有 XR 執行環境都會應用合理的閾值。

建議如需處理扳機與握把按鈕,請以 Float 型別並自行設定閾值。

對於 A/B/X/Y 等純數位按鍵,直接用 Bool 型別即可。

備註

同一控制器於同一設定檔,可將多組輸入綁定到同一動作,XR 執行環境會自動合併輸入。

  • 對於 Bool 輸入,會以「或(OR)」運算合併。

  • 對於 Float 輸入,取所有綁定輸入中的最大值。

  • Pose 輸入則未定義,通常僅採用第一個綁定輸入。

請勿將同一動作集的多個動作綁定到同一控制器輸入。若跨動作集且優先權重疊,行為未定義,部分 XR 執行環境甚至可能拒絕載入你的動作對應,或只採用最先匹配的設定。

我們仍在研究多個動作綁定到同一輸出的限制,雖然場景合理,但 OpenXR 規範目前似乎不允許。

基礎動作定義完成後,接下來要設定對應關聯。

設定檔

在 OpenXR 中,控制器綁定由「互動設定檔(Interaction Profile)」管理。為簡潔起見以下皆簡稱「設定檔」。

之所以用這種通用名稱,是因為設定檔不僅限於控制器,還包含追蹤器、遙控器、追蹤筆,甚至未來可能支援跑步機、觸覺背心等。

警告

需注意,OpenXR 對已支援的硬體裝置有嚴格檢查。標準規範列明數種控制器與其所支援的輸入/輸出,每種 XR 執行環境都必須接受這些設定檔(即使不一定有該硬體)。

新裝置會經由擴充功能新增,XR 執行環境需明確告知支援清單。不支援的裝置設定檔會被拒絕,若載入不支援的輸入/輸出型別甚至可能導致系統崩潰。

因此 Godot 會保存所有可用裝置的 meta 資料、輸入/輸出列表,以及支援來源擴充。你可為欲支援裝置建立設定檔,Godot 會自動排除使用者執行環境不支援的部分。

換言之,若要支援新裝置,可能需更新至較新版本的 Godot。

設計上動作對應系統已考慮此狀況。新裝置推出,或用戶使用你無法測試的裝置時,最終決定權在 XR 執行環境。它會自動選擇最合適的設定檔並做對應調整。

XR 執行環境如何翻配設定檔屬於實作細節,各家差異很大。有些甚至允許用戶端自行編輯動作綁定。

常見做法是先尋找完全匹配的設定檔,找不到則退而求其次使用如「Touch 控制器」等常見檔案,最終再 fallback 到 「簡單控制器」

備註

重點在於:當 XR 執行環境偵測到控制器並套用動作對應時,不會嚴格按照 Godot 動作對應編輯器設定,通常會以你的設定為參考,必要時主動做出調整。

舉例來說,當使用 Touch 控制器設定檔時,可能出現下列任何一種狀況:

  • 可能是 Quest 1 控制器,

  • 也可能是 Quest 2 控制器,

  • 或可能是 Quest Pro 控制器,但沒提供 Quest Pro 設定檔,或當前 XR 執行環境尚未支援 Quest Pro,

  • 甚至可能是完全不同的控制器,但 XR 執行環境以 touch 綁定作為參考。

因此,目前無法確定最終用戶到底使用哪一款控制器。

警告

另外一點易被忽略的是,這些綁定並非固定不變。許多 XR 執行環境允許甚至預期用戶自訂綁定。

目前尚無 XR 執行環境正式開放這類自訂功能,不過 SteamVR 仍可透過 OpenVR 動作對應系統的舊版 UI 進行部分編輯。相關功能正在開發中。

第一個控制器綁定

以下以 Touch 控制器為例,示範如何設定第一個控制器綁定。

點選「新增設定檔」,搜尋 Touch 控制器並加入。若列表中未顯示,可能已經加入。

../../_images/xr_add_touch_controller.webp

此時 UI 上會顯示左右兩側控制器面板,列出所有可用的輸入與輸出。你可點選每個條目旁的「+」將其綁定至動作:

../../_images/xr_select_action.webp

完成綁定設定:

../../_images/xr_touch_completed.webp

每個動作都分別對應左右控制器的相關輸入/輸出,表示兩手皆支援該動作。僅移動動作綁定於右手控制器,因左手搖桿通常另有用途(如傳送)。

開發時需考慮使用者可能自行更改綁定,將移動功能設到左手搖桿等情境。

另外,shoot 與 grab 動作雖為布林型,實際綁定的卻是 Float 型輸入。雖然 OpenXR 可自動轉換,但請詳閱前文有關閾值的注意事項。

備註

你可能會發現有些輸入在列表中重複出現。

例如 X 按鈕會分別出現 X clickX touch,這是因 Touch 控制器內建電容式感應。

  • 僅觸碰 X 按鈕時,X touch 為 true。

  • 實際壓下按鈕時,X click 才會變為 true。

搖桿(Thumbstick)也有類似情況:

  • 僅觸摸搖桿時,Thumbstick touch 為 true。

  • Thumbstick 會輸出搖桿目前推動方向的向量值。

  • 搖桿被往下壓時,Thumbstick click 為 true。

需注意,僅部分 XR 控制器支援觸控感應或搖桿點擊。設計遊戲/應用時,建議將這些功能設定為選用項目。

簡單控制器

「簡單控制器」是 OpenXR 提供的通用後備控制器。我們來對應設定:

../../_images/xr_simple_controller.webp

不難發現,簡單控制器功能極其有限,僅能應付最基本的 VR 遊戲/應用。

所以多數 XR 執行環境僅在萬不得已時才採用簡單控制器,通常會優先嘗試用較常見的設定檔做對應。

備註

由於簡單控制器無法滿足大多數遊戲需求,許多開發者會想為 OpenXR 支援的所有控制器都設綁定。預設動作對應看似如此,但正如前述,這主要是為了從 Godot 3 遷移方便。

OpenXR 工作小組建議:只設定你實際測過的控制器綁定。XR 執行環境設計時已考慮自動重配,效果比開發者盲目設想更佳,且開發者無法保證所有硬體的適用性與體驗。

我們也建議:僅針對實際測試過的裝置建立動作對應。Oculus Touch 控制器現已成多數平台常見後備選項,只要你能在 Meta Rift 或 Quest 上測試並加入設定檔,你的遊戲很可能可相容其他頭盔。

綁定修飾器

動作對應的主要目標之一是讓應用程式無需關心具體硬體型號。但部分硬體因物理設計差異,需對輸入做額外調整,而非僅僅改變綁定關聯,舉凡設定閾值或調整控制器可用輸入等。

綁定修飾器預設為關閉,必須在 OpenXR 專案設定中手動啟用。此外,並非所有執行環境都支援這些修飾器,你需查閱目標執行環境的支援情況,決定是否依賴這些修飾器,或自行實作備援機制。

若你的專案需同時支援多個執行環境且共用同一控制器,可能需針對不同執行環境各自建立專屬動作對應。你可以透過針對不同執行環境匯出的模板,以及自訂 功能標籤 來指定要載入的動作對應檔案。

Godot 的綁定修飾器分為兩種:一種作用於互動設定檔層級,另一種則僅針對單一綁定調整。

互動設定檔層級的綁定修飾器

若要在整個互動設定檔套用修飾器,可於互動設定檔編輯器右側找到修飾器按鈕進行管理。

../../_images/openxr_ip_binding_modifier.webp

點選「新增綁定修飾器」按鈕,即可加入新的修飾器。

警告

由於 Godot 無法預先得知哪些控制器或執行環境支援哪些修飾器,因此不會限制你新增修飾器。若該修飾器不被支援,則會自動忽略。

方向鍵綁定修飾器

方向鍵綁定修飾器會針對控制器的每個搖桿或觸控板輸入,於互動設定檔中新增對應的輸入,將其轉換為四個獨立的上、下、左、右按鍵輸入。

../../_images/openxr_thumbstick_dpad.webp

備註

與擴充功能相關的輸入會以星號標記。

要使用方向鍵綁定修飾器,需先於專案設定中啟用「方向鍵綁定修飾器」擴充功能:

../../_images/openxr_project_settings_dpad_modifier.webp

僅需啟用此擴充功能,即可使用預設設定。

新增修飾器為選用,可進一步微調方向鍵功能的行為。你可針對不同輸入多次新增修飾器,各自調整參數。

../../_images/openxr_dpad_modifier.webp

各設定意義如下:

  • Action Set:設定作用的動作集。

  • Input Path:原始輸入路徑,綁定到新方向鍵輸入。

  • Threshold:觸發方向鍵動作所需的閾值。例如設為 0.6,當搖桿離中心距離超過 0.6 時即觸發該方向。

  • Threshold Released:解除方向鍵動作的閾值。例如設為 0.4,當搖桿回到中心小於 0.4 時即解除該方向狀態。

  • Center Region:定義觸控板中心區域的半徑,超過此值才視為偏離中心,僅支援觸控板。

  • Wedge Angle:每個方向鍵的扇形角度。90 度或以下代表上下左右各自獨立,超過 90 度則會重疊,可能多個方向同時觸發。

  • Is Sticky:啟用後,動作會持續保持按下狀態,直到搖桿或觸控板進入其他方向區塊才解除。

  • On Haptic:當動作觸發時自動啟動的觸覺回饋。

  • Off Haptic:當動作解除時自動啟動的觸覺回饋。

單一綁定層級的綁定修飾器

若要針對單一綁定(某個動作對應某個輸入)套用修飾器,可點選輸入旁的修飾器按鈕設定:

../../_images/openxr_action_binding_modifier.webp

點選「新增綁定修飾器」按鈕,即可加入新的修飾器。

警告

Godot 無法預知每個執行環境與輸入支援哪些修飾器,因此你可自由新增。若執行環境不支援該修飾器,會在執行時自動過濾。若誤加到不支援的輸入,也可能導致執行時錯誤。

請務必在實際硬體及執行環境上測試你的動作對應,以確保設定正確。

類比閾值修飾器

類比閾值修飾器可自訂任意類比輸入(如扳機鍵)觸發布林輸入時的閾值,決定何時算作按下。

使用此修飾器前,須先於專案設定啟用「類比閾值」擴充功能:

../../_images/openxr_project_settings_analog_threshold_modifier.webp

類比閾值修飾器包含以下設定:

../../_images/openxr_analog_threshold_modifier.webp

各設定說明如下:

  • On Threshold:啟動動作的閾值。例如設為 0.6,當類比數值超過 0.6 時即視為按下。

  • Off Threshold:釋放動作的閾值。例如設為 0.4,當類比數值低於 0.4 時即視為釋放。

  • On Haptic:當輸入觸發時自動啟動的觸覺回饋。

  • Off Haptic:當輸入釋放時自動啟動的觸覺回饋。

修飾器的觸覺回饋設定

部分修飾器可設定當閾值觸發時自動啟動的觸覺回饋。

備註

目前所有內建修飾器皆支援此功能,但未來修飾器未必都有此能力。現階段僅支援一種基本觸覺回饋,未來有機會擴增更多類型。

觸覺震動

觸覺震動功能可設定簡單的震動脈衝:

../../_images/openxr_haptic_vibration.webp

可自訂以下選項:

  • Duration:脈衝持續時間(單位:奈秒),設為 -1 則由執行環境自動選擇最適合當前硬體的短脈衝時長。

  • Frequency:脈衝頻率(Hz),設為 0 則由執行環境自動選擇最適合當前硬體的短脈衝頻率。

  • Amplitude:脈衝的振幅。