隨著VR生態的日益增長,以及Valve Knuckles控制器的逐漸完善,SteamVR未來能夠提供給用戶更多的交互方式,比如手指跟蹤和力反饋。近期,Valve在Unity資源商店中將SteamVR插件更新到了2.0版,XR技術研習社將根據官方博客和SDK文檔對此次更新進行介紹,本文同時也是《HTC VIVE 交互開發實例教程》第52課備課內容。

以下為本文將要涵蓋的議題:

1. 概述

2. 重要更新:Input System

3. 動作(Actions)

3.1 骨骼輸入

3.2 振動輸出

4. 動作集(Action Sets)

5. SteamVR Input 窗口

6. 測試動作

7. 動作綁定

8. 在代碼中使用動作

9. Interaction System 的變化

10.VRTK 是否能夠繼續結合 SteamVR 2.0 使用

1. 概述

三年前,SteamVR SDK for Unity插件的第一個版本在Unity資源商店發布,在以後的時間裡,VR生態發生了很多變化,比較顯著的是出現了很多不同類型的控制器。

隨著越來越多的VR設備推出,控制器類型逐漸趨向於碎片化。每當有新的控制器發布,都會給開發者帶來一些額外的工作量——遊戲項目需要修改交互代碼以適配新的設備。從開發層面上來看,不同的控制器具有不同的鍵值映射,所以,當現有 VR 應用程序移植到另外一個VR平台的時候,需要針對目標平台進行交互適配。鑒於此,V社為Unity開發者推出了 SteamVR Unity Plugin 2.0(以下簡稱SteamVR 2.0),能夠使開發者在編程中專註於用戶的動作,而不是具體的控制器按鍵。

2. 重要更新:Input System

SteamVR 2.0 的重要更新是加入了 Input System。推出Input System的目的,是為了更加符合OpenXR標準,以及配合即將正式推出的Knuckles控制器。目前多數主流VR平台均加入了OpenXR開放標準,如下圖所示:

Input System與之前處理用戶輸入有顯著的不同,使用SteamVR Input System,開發人員可以在應用程序之外定義默認的動作並與按鍵進行綁定,而不需要將輸入視為某一特定設備的特定按鍵。這樣新的設備可以快速適配應用程序,無需更改代碼。比如,當開發者檢測玩家是否抓取某個物體的時候,不是檢測Vive控制器的Trigger鍵或Oculus Touch控制器的Grip鍵是否被按下,而是檢測預定義的"Grab"動作是否為True即可。作為開發者,可以在SteamVR中為Grab動作設置默認按鍵和閾值,當程序運行時,也可修改這些數值以滿足玩家的個人偏好。基於這種機制,不光能夠解決控制器碎片化的問題,也可以快速適配未來發布的設備。

3. 動作(Actions)

Input System 的核心概念是動作(Action),基於動作的輸入系統對於遊戲引擎來說更有意義, Unreal一直在沿用這種方案,而Unity目前在開發中的輸入系統也將遵循這一原則。開發者需要放棄之前關於「按下某個按鍵發生什麼事情」的思想,取而代之的是使用「做出某個動作發生什麼事情」的思想。

SteamVR 2.0將動作抽象為以下6種類型,簡介如下:

  • Boolean類型的動作代表只有兩種狀態的動作——True或False,比如抓取(Grab)動作,只有抓取或未抓取兩種狀態,不存在中間狀態。在Unity中對應類為SteamVR_Action_Boolean。
  • Single類型的動作能夠返回0~1之間的數值,比如 Trigger 鍵按下到鬆開的過程。在Unity中對應類為SteamVR_Action_Single。
  • Vector2類型動作能夠返回二維數,比如Touchpad上的觸摸或手柄搖桿。使用這樣的數值能夠控制物體在四個方向的運動,典型的應用時使用Touchpad控制無人機或小車的運動。在Unity中對應類為SteamVR_Action_Vector2。
  • Vector3類型的動作能夠返回三維數值,在Unity中對應類為SteamVR_Action_Vector3。
  • Pose類型的動作表示三維空間中的位置和旋轉,一般用於跟蹤VR控制器。在Unity中對應類為SteamVR_Action_Pose。
  • Skeleton類型的動作能夠獲取用戶在持握手柄控制器時的手指關節數據,通過返回數據,結合手部渲染模型,能夠更加真實的呈現手部在虛擬世界的姿態,雖然不及像LeapMotion等設備獲取手指輸入那樣精確,但是足以獲得良好的沉浸感。在Unity中對應類為SteamVR_Action_Skeleton。

3.1 骨骼輸入

對於骨骼輸入,Knuckles控制器為SteamVR體驗帶來了手指跟蹤功能,能夠估算用戶手指的位置,然後將數據傳遞給驅動程序,驅動程序將其對應解析到手部模型的31塊骨骼上,從而給用戶帶來更好的沉浸式體驗。該功能並不是Knuckles所獨有,SteamVR還能夠為HTC Vive和Oculus Touch這樣的設備提供手指狀態估算,比如判斷手部是否打開,手指是否放置在Touchpad上。同時Valve公司還將與Microsoft展開合作,以增加對Windows MR控制器的支持。

默認情況下,運行Interaction System示例場景中能夠同時看到手部和控制器模型,此外,還有一個輔助組件SteamVR_Behaviour_Skeleton,如下圖所示。有關該組件的使用,可以參考Interaction System的示例場景。

3.2 振動輸出

以上是介紹的都是輸入動作,另外,目前還有一種輸出動作——振動,用於觸發VR控制器上的觸覺反饋,調用方法如下代碼所示:

SteamVR_Input._default.outActions.Haptic.Executefloat secondsFromNow, float durationSeconds, float frequency, float amplitude, SteamVR_Input_Sources inputSource);

4. 動作集(Action Sets)

動作通過動作集進行邏輯上的分組,以方便進行組織和管理。在Unity中對應的類為SteamVR_ActionSet。在不同的場景或應用程序之間可以切換使用不同的動作集,比如,應用程序中有一個場景是在地球上拾取並投擲物體,而另一個場景則是在太空中飛行,那麼這兩個場景可以使用不同的動作集。同時,當針對新設備進行交互適配時,開發者只需對動作進行配置,而不必修改項目代碼。比如,使用 Vive 控制器時,定義了一個Fire動作,當需要支持 Rift Touch 時,只需通過配置Touch控制器上符合 Fire 動作的鍵值即可。

SteamVR插件默認包含了三套動作集default、platformer、buggy,開發者也可以在SteamVR Input窗口中自行添加或刪除動作集。

使用組件SteamVR_ActivateActionSetOnLoad可以在場景中自動激活和停用指定的動作集。對應激活和停用的方法是在Start()和OnDestroy()中實現。如下圖所示:

5. SteamVR Input 窗口

在Unity編輯器中,使用 Window > SteamVR Input 命令,打開SteamVR Input 窗口。在SteamVR 2.0中,使用SteamVR Input窗口作為入口,對所有動作進行管理。初次導入SteamVR 2.0並運行程序時,會彈出一個對話框,提示沒有actions.json文件,並詢問是否要使用默認值。如下圖所示:

選擇Yes,會將默認的actions.json文件以及一些常見的控制器相關綁定文件複製到當前項目的根目錄下,如下圖所示:

這些文件將在程序運行時被載入進來,並在程序最終構建時被複制到與可執行文件同級的目錄下。複製完成後,SteamVR Input窗口將讀取文件信息並展示其包含的動作集合以及動作集合下的所有動作。如下圖所示:

在Actions欄的右下角,可以點擊加減號按鈕添加或刪除動作。每個動作具有名稱(Name)、類型(Type)、本地化字元串(localization strings)等欄位。其中,類型對應上節介紹的動作類型;本地化字元串是面向用戶進行綁定的動作名稱,開發者可以通過SteamVR API直接訪問動作以及動作集。

當點擊Save and Generate按鈕後,插件將為動作以及動作集生成可編程訪問的對象類,將它們放置在項目的SteamVR_input目錄下,如下圖所示:

這些對象可以在相關組件的下拉列表中進行選擇,如下圖所示:

在項目代碼中,使用SteamVR_Input類可以靜態引用每個動作和動作集,在每個動作集中,可以找到其包含的動作的引用,如下代碼所示:

void Update()
{
if(SteamVR_Input._default.inActions.Teleport.GetStateUp(SteamVR_Input_Sources.Any)) {
Teleport();
}
}

以上代碼實現的功能為:當檢測到任意控制器發出default動作集中包含的Teleport動作時,執行Teleport()函數。

6. 測試動作

選擇 Window > SteamVR Input Live View 命令,即可打開一個測試輸入窗口。運行程序,此時該窗口將實時展示所有動作集合的狀態。如下圖所示:

當一個動作的值發生變化時,對應右側會突出顯示綠色,然後逐漸消失。

7. 動作綁定

創建動作以後,需要將動作進行默認綁定。打開VR控制器,保持SteamVR客戶端開啟,在SteamVR Input窗口中,點擊Open binding UI按鈕,此時將使用操作系統默認的網頁瀏覽器打開SteamVR動作綁定頁面。在此頁面中選擇需要綁定的控制器,點擊Edit按鈕,進入綁定編輯頁面,如下圖所示:

All right,像不像實況足球的手柄設置?V社是一家遊戲公司。這樣,對開發者來說,控制器也像對遊戲玩家那樣變得友好了。

在動作編輯頁面中,點擊每個按鍵旁邊的加號按鈕, 彈出窗口會詢問將此按鍵綁定為哪種模式,如下圖所示:

通常情況下,Single類型的動作可以設置為TRIGGER,Boolean類型的動作可以設置為BUTTON。設定以後,在按鍵左下角點擊編輯按鈕,在顯示為None的位置指定相應的動作,如下圖所示:

所有動作綁定完畢,點擊頁面底部的Replace Default Binding按鈕,會將綁定設置保存到配置文件當中。在程序運行時,無論是開發者還是遊戲玩家,都可以再次修改綁定配置,並且能夠反映到遊戲當中。

默認情況下,每個控制器上相同的按鍵綁定相同的動作,如果想為每個控制器設置不同的動作,比如,左手控制器按下Touchpad實現傳送,而右手控制器按下Touchpad使用指針選擇物體,那麼在這種情況下,可以取消勾選頁面中的Mirror Mode複選框,然後分別為每個控制器指定不同的動作。

在綁定編輯界面中同樣可以進行動作測試,點擊頁面底部的Input Debugger按鈕進入測試頁面,在此頁面中,將實時顯示各動作的狀態、動作綁定的按鍵、控制器的實時數據等信息,如下圖所示:

8. 在代碼中使用動作

此處以訪問platformer動作集下的Move動作為例,演示如何獲取動作狀態,執行以下步驟:

  1. 打開SteamVR示例場景Simple Sample,選擇遊戲對象[CameraRig],為其掛載SteamVR_ActivateActionSetOnLoad組件,並指定啟用platformer動作集,如下圖所示:

2. 新建C#腳本,並命名為GetMoveAction.cs,編寫代碼如下所示:

using UnityEngine;
using Valve.VR;
?
public class GetMoveAction : MonoBehaviour
{
void Update()
{
if (SteamVR_Input.platformer.inActions.Move.GetChanged(SteamVR_Input_Sources.Any))
{
Vector2 pos = SteamVR_Input.platformer.inActions.Move.GetAxis(SteamVR_Input_Sources.Any);
Debug.Log(pos);
}
}
}

3. 返回場景,將此腳本掛載到任意遊戲對象上,保存場景運行程序,在任意控制器上觸摸Touchpad時,將在控制台輸出如下信息:

9. Interaction System 的變化

從功能層面來看,本次更新在Interaction System中並沒有添加太多特性,這從Interaction System的更新文檔中也可得出此結論,如下圖所示:

Interaction System的示例場景進行了重新設計,如下圖所示:

在目前的示例場景中,除包含SteamVR 2.0之前的大部分演示外,還加入了一些新的特性。比如,對投擲(Throwing)部分做了擴展、添加了遙控器和遙控車、簡易的推動按鈕、手榴彈,以及一些關於Hand的示例。

  • 在Throwing部分中,目前的示例能夠實現基於速度估計的交互,類似於另外一個VR開發工具NewtonVR能夠實現的效果——被抓取的物體不會直接穿過固定靜止的障礙物,而是跟隨Hand沿障礙物邊界滑動。所有這些交互相關的參數都可以在Throwable組件中進行設置。
  • Remotes部分有兩個簡易控制器,提供了一種與物體進行間接交互的演示。如下圖所示。
  • 在場景中的Skeleton部分,可以通過點擊按鈕來顯示和隱藏控制器模型,以及切換不同的手部模型,如下圖所示:

隨著版本的更新,Interaction System已經隨之支持Input System。在源代碼中,可以看到Interaction System 開始使用 Input System 配置的行為進行交互驅動,如下圖所示:

所以讀者可通過閱讀 Interaction System 的源代碼進一步學習 Input System的使用。

10.VRTK 是否能夠繼續結合 SteamVR 2.0 使用

通過以上論述可見,如果VRTK沒有新版更新的話,理論上來說並不能使用 VRTK(當前版本為 3.2.1) 結合 SteamVR 2.0 進行開發,除非克隆VRTK源碼,自行對其進行修改。這在 Asset Store 中也可找到了印證,如下圖所示:

所以,當前版本的 VRTK (3.2.1)並不支持 SteamVR 2.0。使用 VRTK 的開發者可繼續使用 SteamVR 1.2.3 進行開發,SteamVR Plugin 的過往版本可訪問:github.com/ValveSoftwar 進行下載。

推薦閱讀:

相关文章