Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
XR 動作對應
Godot 的 XR 系統中包含動作對應功能。目前此系統屬於 OpenXR 模組。未來預計也會納入 WebXR,因此本文件統稱為 XR 動作對應系統。它幾乎完全依照 OpenXR 內建的動作對應系統實作。
XR 動作對應系統會將 XR 控制器的輸入、空間定位資料與輸出公開給您的遊戲/應用程式。其原理是公開可自訂的命名動作,並將這些動作綁定到 XR 裝置上的實際輸入與輸出。
由於 XR 動作對應目前屬於 OpenXR 模組,因此必須於專案設定中啟用 OpenXR 才能使用本功能:
接著您會在畫面下方看到 XR 動作對應介面:
備註
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 的動作集。請按下 按鈕:
表格中的欄位意義如下:
欄位 |
值 |
說明 |
|---|---|---|
1 |
my_first_action_set |
This is the internal name of the action set. OpenXR doesn't specify specific restrictions on this name other than size, however some XR runtimes will not like spaces or special characters. |
2 |
我的第一組動作集 |
這是人類可讀的動作集名稱。部分 XR 執行環境會在設定介面等地方顯示此名稱給使用者。 |
3 |
0 |
這是動作集的優先順序。若多個啟用中的動作集將動作綁定到相同控制器的輸入或輸出,則優先值最高的動作集會決定要更新的動作。 |
動作
在 XR 動作對應中,「動作」代表遊戲/應用程式可互動的行為。例如你可定義一個動作 Shoot,當對應輸入啟動時,將觸發場景中 XRController3D 節點的 button_pressed 訊號,參數 name 會是 Shoot。
你也可以主動查詢動作目前狀態,例如 XRController3D 節點中有 is_button_pressed 方法。
動作可對應輸入或輸出,每個動作有其型別,決定其行為。
Bool型別用於離散輸入(如按鍵)。Float型別用於類比輸入(如扳機)。
這兩種型別可互換,OpenXR 會自動在 Bool 與 Float 之間做轉換。你可透過 XRController3D 節點的 get_float 取得 Float 型別動作的數值,且當數值變動時會觸發 input_float_changed 訊號。
備註
當以按鍵方式查詢類比輸入時,會套用閾值。該閾值目前完全由 XR 執行環境管理,未來 Godot 預計將開放部分調整權限。
Vector2 型別用於軸向輸入。例如觸控板、搖桿等會以向量輸出。你可經由 XRController3D 節點的 get_vector2 取得值,數值變動時會發送 input_vector2_changed 訊號。
Pose 型別表示空間追蹤輸入。OpenXR 支援多種「姿勢」輸入:如 aim、grip、palm。你的 XRController3D 節點會依照 pose 屬性綁定的動作自動定位。
備註
Godot 的 OpenXR 實作也提供名為 Skeleton 的特殊姿勢,用於手部追蹤。這個姿勢會由動作對應系統之外的 skeleton 動作自動提供,只要支援手部追蹤就會存在,無需另外綁定動作即可使用。
最後,唯一的輸出型別是 Haptic,可設定觸覺回饋強度(如控制器震動)。控制器可有多組觸覺輸出,OpenXR 也即將支援觸覺背心等裝置。
現在我們來為瞄準姿勢新增動作。請在動作集下方點選「+」按鈕:
表格中的欄位意義如下:
欄位 |
值 |
說明 |
|---|---|---|
1 |
aim_pose |
這是動作的內部名稱,OpenXR 僅限制長度,部分 XR 執行環境不接受空白或特殊符號。 |
2 |
瞄準姿勢 |
這是動作的顯示名稱,部分 XR 執行環境會於設定等介面顯示給使用者。 |
3 |
姿勢 |
此動作的型別。 |
OpenXR 規範多種可綁定的輸入姿勢,實際支援的姿勢因控制器而異,目前 OpenXR 定義的有:
大多數控制器的 aim 姿勢會對應到控制器前方微距位置,並朝向正前方。這很適合用於雷射指標或武器槍口等對準應用。
大多數控制器的 grip 姿勢對應控制器握把按鈕處。不同控制器、甚至同型號於不同 XR 執行環境下方向可能會不同。
大多數控制器的 palm 姿勢對應手掌心握住控制器的位置。此為較新姿勢,並非所有 XR 執行環境皆支援。
備註
如需手部追蹤,目前各家 XR 執行環境實作差異極大,因此動作對應暫不適合用於手部追蹤。相關改進正在推進中,請持續關注。
以下列舉一個簡單射擊遊戲/應用程式的動作清單:
我們新增的動作有:
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 控制器並加入。若列表中未顯示,可能已經加入。
此時 UI 上會顯示左右兩側控制器面板,列出所有可用的輸入與輸出。你可點選每個條目旁的「+」將其綁定至動作:
完成綁定設定:
每個動作都分別對應左右控制器的相關輸入/輸出,表示兩手皆支援該動作。僅移動動作綁定於右手控制器,因左手搖桿通常另有用途(如傳送)。
開發時需考慮使用者可能自行更改綁定,將移動功能設到左手搖桿等情境。
另外,shoot 與 grab 動作雖為布林型,實際綁定的卻是 Float 型輸入。雖然 OpenXR 可自動轉換,但請詳閱前文有關閾值的注意事項。
備註
你可能會發現有些輸入在列表中重複出現。
例如 X 按鈕會分別出現 X click 與 X touch,這是因 Touch 控制器內建電容式感應。
僅觸碰 X 按鈕時,
X touch為 true。實際壓下按鈕時,
X click才會變為 true。
搖桿(Thumbstick)也有類似情況:
僅觸摸搖桿時,
Thumbstick touch為 true。Thumbstick會輸出搖桿目前推動方向的向量值。搖桿被往下壓時,
Thumbstick click為 true。
需注意,僅部分 XR 控制器支援觸控感應或搖桿點擊。設計遊戲/應用時,建議將這些功能設定為選用項目。
簡單控制器
「簡單控制器」是 OpenXR 提供的通用後備控制器。我們來對應設定:
不難發現,簡單控制器功能極其有限,僅能應付最基本的 VR 遊戲/應用。
所以多數 XR 執行環境僅在萬不得已時才採用簡單控制器,通常會優先嘗試用較常見的設定檔做對應。
備註
由於簡單控制器無法滿足大多數遊戲需求,許多開發者會想為 OpenXR 支援的所有控制器都設綁定。預設動作對應看似如此,但正如前述,這主要是為了從 Godot 3 遷移方便。
OpenXR 工作小組建議:只設定你實際測過的控制器綁定。XR 執行環境設計時已考慮自動重配,效果比開發者盲目設想更佳,且開發者無法保證所有硬體的適用性與體驗。
我們也建議:僅針對實際測試過的裝置建立動作對應。Oculus Touch 控制器現已成多數平台常見後備選項,只要你能在 Meta Rift 或 Quest 上測試並加入設定檔,你的遊戲很可能可相容其他頭盔。
綁定修飾器
動作對應的主要目標之一是讓應用程式無需關心具體硬體型號。但部分硬體因物理設計差異,需對輸入做額外調整,而非僅僅改變綁定關聯,舉凡設定閾值或調整控制器可用輸入等。
綁定修飾器預設為關閉,必須在 OpenXR 專案設定中手動啟用。此外,並非所有執行環境都支援這些修飾器,你需查閱目標執行環境的支援情況,決定是否依賴這些修飾器,或自行實作備援機制。
若你的專案需同時支援多個執行環境且共用同一控制器,可能需針對不同執行環境各自建立專屬動作對應。你可以透過針對不同執行環境匯出的模板,以及自訂 功能標籤 來指定要載入的動作對應檔案。
Godot 的綁定修飾器分為兩種:一種作用於互動設定檔層級,另一種則僅針對單一綁定調整。
互動設定檔層級的綁定修飾器
若要在整個互動設定檔套用修飾器,可於互動設定檔編輯器右側找到修飾器按鈕進行管理。
按下 按鈕即可新增修飾器。
警告
由於 Godot 無法預先得知哪些控制器或執行環境支援哪些修飾器,因此不會限制你新增修飾器。若該修飾器不被支援,則會自動忽略。
方向鍵綁定修飾器
方向鍵綁定修飾器會針對控制器的每個搖桿或觸控板輸入,於互動設定檔中新增對應的輸入,將其轉換為四個獨立的上、下、左、右按鍵輸入。
備註
與擴充功能相關的輸入會以星號標記。
要使用方向鍵綁定修飾器,需先於專案設定中啟用「方向鍵綁定修飾器」擴充功能:
僅需啟用此擴充功能,即可使用預設設定。
新增修飾器為選用,可進一步微調方向鍵功能的行為。你可針對不同輸入多次新增修飾器,各自調整參數。
各設定意義如下:
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可讓我們定義在動作被釋放時自動啟動的觸覺輸出。
單一綁定層級的綁定修飾器
若要針對單一綁定(某個動作對應某個輸入)套用修飾器,可點選輸入旁的修飾器按鈕設定:
按下 按鈕即可新增修飾器。
警告
Godot 無法預知每個執行環境與輸入支援哪些修飾器,因此你可自由新增。若執行環境不支援該修飾器,會在執行時自動過濾。若誤加到不支援的輸入,也可能導致執行時錯誤。
請務必在實際硬體及執行環境上測試你的動作對應,以確保設定正確。
類比閾值修飾器
類比閾值修飾器可自訂任意類比輸入(如扳機鍵)觸發布林輸入時的閾值,決定何時算作按下。
使用此修飾器前,須先於專案設定啟用「類比閾值」擴充功能:
類比閾值修飾器包含以下設定:
各設定說明如下:
On Threshold:啟動動作的閾值。例如設為0.6,當類比數值超過 0.6 時即視為按下。
Off Threshold:釋放動作的閾值。例如設為0.4,當類比數值低於 0.4 時即視為釋放。
On Haptic:當輸入觸發時自動啟動的觸覺回饋。
Off Haptic:當輸入釋放時自動啟動的觸覺回饋。
修飾器的觸覺回饋設定
部分修飾器可設定當閾值觸發時自動啟動的觸覺回饋。
備註
目前所有內建修飾器皆支援此功能,但未來修飾器未必都有此能力。現階段僅支援一種基本觸覺回饋,未來有機會擴增更多類型。
觸覺震動
觸覺震動功能可設定簡單的震動脈衝:
可自訂以下選項:
Duration:脈衝持續時間(單位:奈秒),設為-1則由執行環境自動選擇最適合當前硬體的短脈衝時長。
Frequency:脈衝頻率(Hz),設為0則由執行環境自動選擇最適合當前硬體的短脈衝頻率。
Amplitude:脈衝的振幅。