最近寫VR項目的時候用到了SteamVR Unity Plugin - v2.0.1插件,感覺比之前用到的SteamVR plugin for Unity - v1.2.2版本改進了很多,就算不用VRTK插件,也能實現很多交互操作了。在此記錄一下新版本插件的中的主要內容。(主要是根據InteractionSystem文檔和自己的理解)
這個InteractionSystem包括一系列腳本,預制件和其他資產資源,這個系統專門設計的輕巧靈活。。其中大多數包含的組件在實際案例中都運用到了,但也包括一些沒有在案例中用到的組件,但是它可能也是有用的。
1.首先概述一下示例場景中包括的預制件和腳本主要的功能:
Player:這個預制件是整個系統的核心,大多數其他組件都依賴於player
Teleporting:傳送預制件處理所有關於傳送的邏輯。
InteractableExample:這個類是一個和手柄進行簡單交互的類。會接收手柄發來的信息並作出反應。
Throwables:這個展示了在游戲中怎樣使用交互系統來創建一些更復雜的能夠被使用的對象。
UI&Hints:這個顯示了交互系統如何處理提示。並且如何使用它和Unity UI控件像按鈕一樣進行交互。
LinearDrive:這是一個稍微復雜的交互,可以通過簡單的直線移動操作對象來控制的目標對象進行螺旋上升和下降。
CircularDrive:這個類主要實現了通過手柄控制一個圓盤的轉動
Longbow:這是案例中使用的長弓。是這個系統創建的更復雜的對象之一。
2.簡單介紹交互系統
交互系統的核心是Player,Hand和Interactable類。Player預制件為場景設置play對象和SteamVR攝像機。這個交互系統通過發送信息給場景中所有可以和手柄進行交互的對象,這個對象再對接收的信息作出反應。並可以設置對象附着到手柄上。為了接收手的信息只要添加Interactable組件到對象上,這個對象就可以根據手的信息作出相應的懸停監測。還包括了一些常用的可交互方式,例如Throwable(扔)或者LinearDrive(直線移動物體)。Player預制件也創建了一個用於模仿鼠標事件可以簡單地用Unity UI控件控制的輸入模式。交互系統也包括一個傳統的第一人稱攝像機,用鍵盤和鼠標控制。鼠標就類似人的一只手一樣。當開發者沒有VR頭顯時,這個模式就非常有用了。
3.Player類的功能介紹
-Player類是一個單例,意味着在一個場景中只有一個Player對象。
-Player主要功能是持續追蹤手柄和頭顯。
-它可以在整個項目中全局訪問,並且交互系統的許多方面都假定Player對象始終存在於場景中。
-不管是VR模式還是2D fallback模式,它都保持追蹤。
-通過Player類使用訪問器允許其他組件以類似的方式運行,而不知道是否正在使用VR頭顯或鼠標/鍵盤。
-2D fallback模式雖然有用,但仍然有限制。此模式主要用於測試非常簡單的交互,僅限於一個手和觸發按鈕。它對於一個團隊在開發中,並不能保證每個人一直都有一個VR頭顯和控制器設備。
-Player的一些有用的屬性:
-hmdTransform:一只返回當前攝像機的transform。可能是VR頭顯和2D fallback camera。
-feetPositionGuess:根據頭顯的位置猜測玩家腳的位置。但不能准確知道腳的位置,根據玩家的站立方式,這可能非常不准確。
-bodyDirectionGuess:類似於feetPositionGuess,根據玩家的站立方式,這可能非常不准確。
注意:在編輯場景中,player類設置使用icons顯示feet和hands。但由於unity工作方式,需要將Core/icons移動到根目錄下Gizmos中,才能起作用。
-關閉2D fallback mode的兩種方式:
1、在build之前,將player的屬性面板中Allow Toggle To 2D取消勾選
2、在PlayerSetting.Player中Scripting Define Symbols增加HIDE_DEBUG_UI。這將會在build時取消2D debug view,但允許在編輯器中使用。
4.Hand類的功能介紹
-Hand類為交互系統完成了大部分繁重工作。
-Hand檢測正在懸停的對象(Interactables)並根據當前的懸停狀態向它們發送消息。
-hand在同一時間只能懸停在一個對象,在相同時間只能有一只hand能懸停在一個對象。
-對象可以附着在手柄上,也可以從手柄上分離。只有一個對象可以是手柄的焦點對象,但是同時可以將多個對象附加到手柄上。
-一旦一個對象從手柄上分離,那么之前附着在手柄上的對象(仍然附着在手柄上)會成為手柄的焦點對象。
-當手柄上沒有任何東西時,它將始終顯示手柄控制器。
-當對象一旦附着在手柄上時,可以給附着在手柄上的對象可以設置一個附着標志物UI來確定手柄和對象的行為。
-根據情況,可以鎖定手柄以懸停在其他物體或任何物體上。
-這些是hand發送給交互物體的信息:
OnHandHoverBegin: 當手柄首次開始懸停在對象上時發送
HandHoverUpdate: 懸停在對象上時,每一幀都發送信息
OnHandHoverEnd: 當手柄停止懸停在對象上時發送
OnAttachedToHand: 當對象附加到手柄上時發送
-HandAttachedUpdate: 附加到手柄上時,每一幀都發送信息
OnDetachedFromHand: 當對象從手柄中分離時發送
OnHandFocusLost: 當附加對象失去焦點時發送,因為其他東西已附加到手柄上
OnHandFocusAcquired: 附加對象獲得焦點時發送,因為前一個焦點對象已從手柄中分離
- 這些是手柄發送給其子對象的消息:
OnHandInitialized: 通過將自己與SteamVR跟蹤控制器的設備ID相關聯來首次初始化手柄時發送
OnParentHandHoverBegin: 當手柄開始懸停在某物上時發送
OnParentHandHoverEnd: 當手柄停止懸停在某物上時發送
OnParentHandInputFocusAcquired: 當游戲窗口獲得輸入焦點時發送
OnParentHandInputFocusLost: 當游戲窗口失去輸入焦點時發送
- 這些成員處理附加和分離:
AttachObject: 將傳入的附加標簽設置在附着對象上
DetachObject: Detaches the object from the hand and optionally restores it to its original parent currentAttachedObject: This returns the in-focus attached object on the hand,if any
- Hand還有一些有用的屬性和函數可用於自定義其行為:
OtherHand: 這是玩家控制的另一只手柄。這對於需要用兩個手柄交互的對象(例如長弓)非常有用。
HoverSphereTransform and Radius: 這可用於自定義手柄的懸停范圍。
HoverLayerMask: 這可以改變,以便手柄只懸停在某些層中的對象上。
HoverUpdateInterval: 根據游戲的要求,可以設置進行懸停檢測的時間間隔。
HoverLock/Unlock: 這用於使手柄僅懸停在某個對象上。當hover locked時,傳入為null將使得手柄不會懸停在任何東西上。此技術用於在傳送arc處於活動狀態時使手柄不懸停在對象上
GetStandardInteractionButton/Up/Down: 這些用於檢查手柄上的扳機的狀態。 這對於也可以與2D fallback一起使用的簡單對象非常有用。 在2D fallback情況下,左鍵單擊用作標准交互按鈕,對象的行為相同。
GuessCurrentHandType: 這使用一些SteamVR函數來確定哪個手柄最左邊哪個是最右邊的。
GetAttachmentTransform: 物體可以使用手上的“attachment transforms”來弄清楚如何附着到手柄上的transform。
5.Interactable類更像是一個標識符。它向Hand標識該對象是可交互的。具有此組件的任何對象都將從Hand接收相關消息。
僅使用以上這3個組件,就可以能夠創建許多不同且復雜的交互式對象。
6.Throwable類的主要功能:
這是最基本的交互式對象之一。
- 當手柄在其上懸停並按下交互鍵(扳機)時,玩家可以拾取此對象。
- 按下扳機時,物體會附在手柄上並保持在那里。
- 當釋放扳機時,手柄的速度都會賦給拋出對象。
- 這可以創建可以拾取和拋出的基本對象。
7.LinearDrive類的主要功能是允許用手柄在開始和結束點之間移動對象,對象的當前位置用於設置LinearMapping。
8.CircularDrive類的主要功能是允許用手柄控制圓盤轉動。對象的當前位置用於設置LinearMapping。
9.LinearMapping值由LinearDrive和CircularDive設置
-映射可用於將簡單的手部交互映射到更復雜的行為。
-一個例子是長弓中的字符串,它使用LinearMapping將弓弦的拉動映射到長弓拉回動畫。
-幾個其他類使用該映射來插入其屬性
LinearAnimation
LinearAnimator
LinearBlendShape
LinearDisplacement
HapticRack
10.VelocityEstimator類可用於根據對象位置的變化估計對象的速度和加速度。在大多數情況下,如果從實際控制器獲得速度和加速度,將獲得更准確的結果,但有時這是不可能的,例如使用2Dfallback hand時。
11.IgnoreHovering類主要功能是,當你希望某對象不進行懸停檢查時,則可以將此組件添加到該對象或特定的碰撞器上。
12.UIElement類的主要功能:
將此組件添加到unity的UI控件上,則手就可以與UI進行交互。
這將生成基於手部交互的鼠標懸停和單擊事件,並通過Unity事件系統發送它們以使用現有的UI控件。
此外,它還將生成一個OnHandClick事件,該事件也將傳遞到點擊的那個手柄。
13.ItemPackage類的主要功能:
-ItemPackage是用於暫時覆蓋手柄的功能的對象集合
-在長弓的例子中,當長弓被手柄拿起后,長弓和手柄就結合在一起,並暫時替代手柄的功能。
-ItenPackages的概念是能夠撿起和放回到物體被撿起的地方。
-一旦附帶ItemPackage組件的對象被拿起,此對象會附着在手柄上,直到此對象被放回。不需要按鈕就可以讓此對象保持在手柄上。手柄仍然可以正常的傳遞消息(與場景中的對象交互),但此對象通常會禁用手柄的某些功能,例如手柄的懸停功能。
14.ItemPackageSpawner腳本處理產生和收起ItemPackage時的邏輯,以及如何在產生后將物品附加到手柄上。還可以處理拾取對象的展示和預覽或者拾取對象的輪廓。
15.ItemPackageReference可以將此組件添加到對象以指示它是組合對象的一部分。
16.PlaySound這個類允許使用更多參數來使用AudioClips。可以接收多個AudioClips並且每次隨機播放一個。還可以隨機播放剪輯的方式。
17.SoundPlayOneShot類專門用於播放一次且不循環播放的聲音或者需要在播放時暫停的聲音。
18.Util類中全是interaction system中用到的工具方法。
19.InteractableHoverEvents當收到手柄傳遞的信息時這個類生成UnityEvents。
20.InteractableButtonEvents此類將手柄按鈕輸入轉換為UnityEvents。
21.ComplexThrowable類當手接觸對象時使用物理關節而不是simple parenting,這允許在手接觸對象時進行更多基於物理的交互。
注意:這個類是實驗性的,還沒有真正運用到場景中,此類的功能是不完整的並且可能有錯誤。
22.DistanceHaptics基於兩個transform之間的距離觸發手柄的震動反饋。
23.Player(Prefab)功能
-這是交互系統的單個部分,它結合了所有基本部分
-這個預制件管理玩家和手部,使他們都可以輕松訪問。
-包括所有SteamVR和2Dfallback的設置
-交互系統的大多數的組件都依賴於Player預制件,並且一些組件假設player和hand都用這種方式設置。
-每個場景只有一個。
24.BlankCOntroller(Prefab)當手柄沒有接觸任何東西時使用,控制器的渲染模型通過SteamVR加載,其所有部件都是鉸接式(articulated)的。