Unity Steam_VR 開發工具插件 VRTK自帶案例分析(第一部分)


VRTK這個工具包提供了很多在Unity3d做VR開發中通用的VR功能,主要包括

1)具有別名的控制器按鈕事件

2)控制世界指針(激光指針)

3)玩家瞬間轉移

4)使用控制器抓起/握住物體

5)使用控制器與物體交互

6)把游戲物體變成交互式的UI元素

這個工具集主要分成三個部分:

1)Prefabs - VRTK/Prefabs/

2)Scripts - VRTK/Scripts/

3)Examples - VRTK/Examples/

DEMO 1  查詢硬件手柄頭顯
在VRTK插件的第一個demo 001_CameraRIg_VR_PlayArea 案例。這個demo 顯示的功能:  按下任一手柄上的按鍵,便載入下一個場景。找到demo場景中##Scene Changer## 游戲物體,打開附加的scene changer腳本,里面有兩個核心的類,以及幾個重要的API。
VRTK_DeviceFinder類:用於在場景中尋找左右手柄、頭顯、返回硬件編號或手柄,頭顯的gameobject。
120422om1zzn16k1wn3kex           120415lv39gfo989uuucnh
重要的API:  
獲得左右手柄的游戲物體
VRTK_DeviceFinder.GetControllerRightHand(); 
VRTK_DeviceFinder.GetControllerLiftHand();
獲得左右手柄對應的硬件編號
VRTK_DeviceFinder.GetControllerIndex(rightHand)

120415n1x48i1gvy14xz8u

按下手柄任一按鍵或鍵盤上的空格鍵,加載下一個場景。ForwardPressed 用於偵測手柄的按鍵是否按下。

120416fj4w8jbk44k7ef4e

120415eryfryrdylqszxk9

上圖中引入第二個重要的類:VRTK_SDK_Bridge, 這是插件封裝了 SteamVR 的比較底層的API: VRTK_SDK_Bridge.IsTriggerPressedOnIndex(controllerIndex) 。 輸入硬件的編號,返回是否按下的布爾值。
 
DEMO 2手柄的輸入事件
封裝成VRTK_ControllerEvent腳本。 針對VR中常見的交互動作: UI點擊,抓住物體,觸發物體功能等,自定義手柄按鍵,綁定這些動作。

120416muhu7ux937xcf97u

pointerToggleButton:激光的顯示開關,激光在VR里相當於鼠標箭頭的指向功能。
pointerSetButton:激光停留的指向目標,觸發目標的功能,相當於鼠標點擊。
grabToggleButton:抓住物體動作,配合使用 VRTK 插件集成的抓取,投擲功能。
useToggleButton:觸發目標事件,比如把手柄放在門把手上,按下這個按鍵,觸發門打開的功能;手柄放在電燈開關上,按下按鍵,觸發電燈開發的功能。 這個和pointerSetButton區別在於后者需要激光落在目標上,才能觸發目標上的功能。
uiClickButton:觸發UI Canvas 目標的事件。
menuToggleButton:游戲目錄顯示開關。
axisFidelity:按鍵按下的強度,完全按下是1,松開時是0。現在只有Trigger按鍵(手部后面扳機)有此屬性。
triggerClickThreShold:扳機要到多大程度,才能使用扳機的觸發功能。如果是0.5,則表示只要按下一半的程度就可以觸發,如果是1,則必須完全按下才能觸發。  
以上是設置各個按鍵在插件中交互的功能, 如果要獲得每個按鍵具體的使用情況,如按下、松開按鍵、手觸摸板的按鍵位置、扳機的按下強度等,則需要在 VRTK_ControllerEvent 注冊對應按鍵的事件。  
在VRTK_ControllerEvents_ListenerExample腳本中,監聽了VRTK_ControllerEvent所有按鍵的事件,和按鍵的參數信息。 如下圖的扳機鍵的按鍵事件。  

120416vlhl1kkwlwolowv1

事件的參數是:手柄的硬件編號、按鈕的按下程度值(扳機鍵專有的屬性)、 觸摸板的觸摸位置和角度(觸摸板專有的屬性)

120416oz3348mwlx3b36k6

 
DEMO 003_Controller_SimplePointe傳送位置
VRTK_Simple Pointer類。該腳本繼承自VRTK_WorldPointer

120416dfs3q4t4qus6s75q

功能的核心是將玩家的位置傳送到激光所指落在的地方, 該腳本應默認放在手柄的prefab上。 其他的參數設置激活顏色、傳送時是否顯示玩家活動區域、激光有效觸碰的層、激光的粗細等。
 
DEMO 004_CameraRig_BasicTeleport
VRTK_BasicTeleport。該腳本配合繼承自VRTK_WorldPointer的子類,如VRTK_Simple Pointer,添加此腳本后才可以位移傳送。  

120416yurmezdwrvmdn55y

參數
1)傳送時黑屏:模擬眨眼動畫,過渡更自然。
2)黑屏時間:隨傳送距離遠近成正比的黑屏時間。假如傳送的位置比較遠,則黑屏時間更久。數值越大,黑屏時間越長,數值為0時,不受距離遠近影響。
3)頭部位置:以頭部為基准,作為傳送的位置。未打鈎,則是玩家可玩區域的中心位置作為傳送的目標點。可玩區域不能和游戲環境交叉,最大化玩家活動空間。
4)禁止傳送物體的標簽:如果傳送的目標位置的物體標簽和此相同,則不能傳送。
5)作為第四個功能的補充:可以添加 VRTK_TagOrScriptPolicyList 腳本中添加多個禁止傳送的物體標簽。
6)navemesh 邊緣限制:在 navemesh 上傳送,如果在 navemesh 的邊界,則禁止傳送,數值是離邊界的距離范圍。 

120417jicqcrllooizqqiz

 
DEMO 005_Controller_BasicObjectGrabbing 
手柄上添加的組件 
抓取物體  VRTK_InteractGrab,這個腳本用來抓取物體,抓的按鍵在 VRTK_ControllerEvent 腳本中設置。

120418vdl8ffrh1xx51qzh

controllerAttachPoint:被抓的物體,被附加在哪個物體上,默認是手柄的圓環處。
HideController On Grab:抓住物體時,隱藏手柄。
Hide Controller Delay:延遲幾秒后隱藏手柄。
Grab Precognition:提前預判抓取物體。對應快速運動的物體,我們可能需要提早按下抓取按鍵才能抓住物體,數值是提前的時間值,值越大,可提前的抓取時間越長。
Throw Multiplier:把物體扔出去時,速度的倍增值。
Create Rigid Body When Not Touch:在碰到物體時才創建 RigidBody。默認情況下手柄也創建 Rigidbody,這就可以和物體在物理上 碰撞。
 和物體接觸 VRTK_InteractTouch
Hide Controller On Touch:接觸物體時隱藏物體。
Hide Controller Delay:接觸物體后延遲幾秒后隱藏物體。
Global Touch HighLight Color:如果被接觸的物體上未設置接觸高亮顏色,則用此顏色來對改變目標的顏色。
Custom RigidBody Object:自定義用於判定接觸的剛體物體,如果沒有的話,會自動在子層級創建一個剛體物體。
交互物體上應該添加的腳本
120417vn30hnmue02mds71 
 
VRTK_InteractableObject 需要有rigidbody組件和collider組件
1) Touch options 接觸
HighLight OnTouch:接觸時高亮顯示物體顏色。
Touch HightLight Color:高亮的顏色。
Rumble On Touch:接觸時的反饋震動強度和時間。
Allow Touch Controller:規定哪個手柄可以接觸這個物體。
Hide Controller On Touch:覆蓋是否隱藏手柄的設置,default是根據手柄的設置。
2) Grab Options 抓取
IsGrabbable:是否可以被抓取。
Is droppable:松開時是否掉落。
Is swappable:是否可替換。如果不行,則必須先把物體丟掉。
Hold Button To Grab:按住才能保證物體不掉落。
Grab Override Button:覆蓋手柄的抓取按鍵設置。
Rumble On Touch:接觸時震動,同上。
Allowed Grab Controllers:規定哪個手柄可以接觸這個物體。
Precision Grab:精准抓取。如果是,則抓取的位置是剛接觸到物體的點,而不是默認的物體中心位置。
Right Left Snap Handle:被抓物體的抓取點,該游戲物體應該放在被抓物的子層級下。
StayGrabbed On Teleport:傳送后仍然抓住物體,否則物體丟掉。
GrabAttach Mechanic:被抓物體的依附機制。Fixed_joint 鏈接到fixed Joint 上,這是比較常用的物理上的固定位置鏈接; Spring_joint 和Fixed Joint類似,但是有點手臂關節,可以拉伸彎曲伸直;track Object 不靠joint 鏈接,而是讓被抓物跟隨手柄的位置方向; rotator_Track 比較適合門、車駕駛把手這種有固定轉軸的物體,它只能在受轉軸的約束下,根據手柄的抓取位置來調整旋轉;child of controller 作為手柄的子物體;climbable固定不動的交互物體。
3) Use options 使用
Use only if Grabbed:只有在被抓取時才可以被使用。
Hold Button to Use:長按手柄按鍵才可以使用。
Use Override Button:自定義操作按鍵。
Pointer activates Use Action:如果打鈎,當手柄發射的激光落在交互物體上,於此同時如果Holon to use沒有打鈎,則使用該物體,Holon to use打鈎了,則要按住使用按鍵才可以使用該物體。

120417ah4nxb42112bqk11

該腳本可以 為交互物體增加一個外輪廓顏色。
 
VRTK_InteractableObject擴展
DEMO 006_Controller_UsingADoor
該例子用了一個開門的交互來擴展VRTK_InteractableObject 腳本

120417gyffitszs32qbq4y

接觸VRTK_InteractableObject類,覆蓋開始使用物品的方法,在此方法中寫入交互動作的邏輯方法。此外還有物體被接觸時,抓取時,接觸接觸,結束抓取動作發生時調用的函數,可以覆蓋此方法,自定義擴展你的交互動作。
120418d4e54lpqffcs5t5f
注意:手柄上應該添加下圖腳本,否則無法使用物體
 

120417ah4nxb42112bqk11

 
DEMO 007_CameraRig_HeightAdjustTeleport  高度升降傳送

120418tsreepdq3eqfeq28

 此腳本繼承VRTK_BasicTeleport,不像DEMO 4場景只能水平面平移傳送,它可以傳送高低不同的地面,而且還可以模擬走上下樓梯的位移感。 上圖中紅框中是擴展的功能參數。 
Play space falling:是否能下落
Play space fall restriction:下落條件, 規定哪個手柄位於當前平面內,就不會下落
Use gravity:是否自由落體加速度
Gravity Fall Height:超過多少高度差,才開始自由落體
Blink Y threshold:高度落差超過多少值時,才會模擬黑屏眨眼的效果
Floor Height Tolerance:找過這個數值時,才會有上升和下降的位移
 
DEMO 008_Controller_UsingAGrabbedObject
和第6個場景原理類似,都是繼承VRTK_InteractableObject 腳本,物品的使用功能拓展。
 
DEMO 009_Controller_BezierPointer
拋物線傳送偵測。和VRTK_Simple Pointer功能類似,不同的是使用拋物線來代替激光直線獲取傳送的位置
 

120418og3q2zz7ge71g8h8

紅框內是額外的參數,  設置拋物線的最長有效距離,  拋物線 中的物體, 落地的光標物體設置等,沒有什么額外特別的東西
 
DEMO 010_CameraRig_TerrainTeleporting 地形傳送
此例子沒有演示新的功能,只是展示了可以在地形上傳送
 
DEMO 011_Camera_HeadSetCollisionFading
頭部碰撞到物品后黑屏眨眼效果,提示玩家已經和游戲中物體相接觸,讓其返回到正常的區域。附加在Camera(eye) 上
 

120418y31lgn13arhzaouh

 120419enenkmkx0nnttcwc

 
DEMO 012_Controller_PointerWithAreaCollision
傳送的位置附近的物品如果和玩家可活動范圍碰撞器的相接觸,將影響傳送位置的最終位置,使其在合理的范圍內。
開啟可玩區域碰撞體
 

120419ada444oqk2ak6g6d

 
DEMO 013 演示了多個物體抓取和使用的功能
 
DEMO 014 演示了抓取物品握住的位置
120419f4pp4if4d35y3fyh
 主要是這里的參數設置,這些參數的意義之前已經有說明
  
DEMO 015_Controller_TouchpadAxisControl
 演示手指在手柄觸摸板的觸摸位置vector2 (x,y),來控制小車的移動方向,手柄的扳機,控制小車跳起的動作。基本思路是:一個腳本監聽手柄的輸入事件, 將事件的相關值傳入到小車的控制器。 
監聽手柄按鍵
 

120419mt4zmf4hh1t2y24h

 傳入到小車的控制運動的腳本
 

120419liei6ir3rrrb4ymr

 小車的運動部分函數
 

120419bz1okyj17jkkcso4

DEMO 016_Controller_HapticRumble

手柄震動
當藍色盒子上的劍和紅色盒子撞擊時,觸發手柄震動
 

120420l3wcbiciaz6q3jh6

 
基本思路是劍的物體碰撞器偵測到碰撞時,獲取手柄的運動速度,來決定震動的強度。 
如下圖,controllerAction和ControllerEvents對應的手柄身這兩個腳本。 

120420et9hiciikxt8cqqn

 關鍵的震動方法是:有 VRTK.ControllerAction.TriggerHapticPulse ( 震動強度, 震動持續時間,震動間隔時間)。
 
DEMO  017_CameraRig_TouchpadWalking
使用觸摸板來控制人物行走,以及在低矮的洞穴中蹲走時碰到頭頂的碰撞體,返回到能正常直立站立的位置。附加在此物體上
 

120420rjzr7ddlwy8j06kj

VRTK_PlayerPresence 讓人物有碰撞體,且頭部上方有碰撞體時,如果不蹲着走,就會強制返回可以正常站立的位置。 
HeadSet Y position:頭部碰撞體離頭頂向下的偏移值, 這樣可以通過更矮的擋板
Ignore Grabbed Collisions:忽略交互物體的碰撞效果,建議勾上
Reset Position On Collision:在低矮的洞穴中蹲走時碰到頭頂的碰撞體,返回到能正常直立站立的位置
Falling physics only:如果打鈎,則可以自由落體下降
  VRTK_TouchpadWalking通過觸摸板的觸摸位置來定位移動方向
 參數:
leftController ,rightController:如果勾選則可以控制移動。
Max Walk Speed:最大行走速度,如果觸摸位置離中心位置越近,移動速度越慢。
Deceleration:行走結束時的減速效果,防止惡心。
MoveOnButtonPress:按下哪個按鍵時才能觸發移動(前提觸摸板也要輸入)。
Device For Direction:移動的方向以哪個設備為基准。頭顯朝向,還是左右手柄的正方向。
 
DEMO  018_顯示當前幀數
把這個prefab 拖到場景中就可以顯示當前幀數
 

120420son9irlss3miul5r

 
DEMO 019_Controller_InteractingWithPointer
用手柄激光和物體交互
 
VRTK_interactionObject的pointer activates use 打鈎后,就可以用激光和物體交互,如果HolonToUse 沒有勾選,那么激光落在物體上,就直接使用該物體。如果HolonToUse勾選了,那就需要激活指在物體上,同時按下扳機按鍵,才使用物體。
 
DEMO 020_CameraRig_MeshTeleporting
在各種形狀的網格上傳送
 

120420wmfhn64mmpxfzf8f

 120421j4hepjjjnhlq224f

 

120421tlsfaleraren5lu5

 激活指針傳送和拋物線在復雜網格模型上的傳送效果,沒有新的功能演示
 
DEMO 021_Controller_GrabbingObjectsWithJoints
物體不同的交互方式
打開寶箱
 

120421zg4m46lk4mmqcvjf

 盒子的上半部分添加轉軸組件
 

120421xf3sfr7q35ht7hrh

設置轉軸的轉動軸向,位置,就可以像真實打開箱子一樣。
箱子的把手需要添加以下腳本
 

120421mfggfwktkiqgdj09

 VRTK_Interactable Object 是必須要添加的腳本,它保證可以被手柄抓取 rigidbody和fiexed joint是用來連接上半部分的盒子,固定把手的位置 

120421j3jtnnqeqa665a6a

  有一定活動區間關節物體
使用character joint 來確定上下關節的連接關系(每個關節也要添加rigidbody 組件)
 

120422kzari6b21bbj1bie

其關節上的VRTK_InteractableObject 的Grab Attach Mechanic 要設置成 spring_joint

Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1

該關節交互組件繼承重寫了 抓取和松開物體時的方法,   抓取時,剛體模擬動力學運動,松開時,就停止模擬,防止受重力影響

Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1

 抽屜

Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1

和打開盒子相似的設置,不過約束的方式不一樣,用的是configurable joint 注意約束軸向和可活動距離約束數值設置

Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1

Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1

VRTK_InteractableObject 的抓取方式

Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1

DEMO 022_Controller_CustomBezierPointer

自定義拋物線的外觀

DEMO 023_Controller_ChildOfControllerOnGrab

弓箭的思路   抓取方式:作為手柄子物體,跟隨手柄運動

 Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1 Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1

 制作弓箭的彎曲動畫

Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1

 大致思路:

 1)手柄抓取弓時,弓的interactableObject 組件查詢是哪個手柄握住弓,得到該手柄的VRTK_ControllerEvents,和VRTK_ControllerActions。前者監聽手柄的輸入,后者控制手柄震動,同理 獲得緩沖拿箭的手柄的這兩個組件。

Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1

 2)如果當前弓上有箭頭,且手柄握着箭,箭頭位置歸零,箭頭對向瞄准處。拉弦時,弓箭的朝向有拉弦手柄到握弓手柄方向。根據拉弦強度播放拉弓動畫。如果拉弦的手柄松開,發射弓箭,初始化弓箭的剛體速度方向。

3)被握住箭碰到弓,  將箭定位到拉弦處的虛擬定位物體的子層級下,箭的方向由拉弦處位置朝向弓把手上箭的放置位置。

DEMO 024_CameraRig_ExcludeTeleportLocations

限制可傳送的物體

Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1

在這里寫入的標簽,無法識別傳送到該物體表面。可以寫入多個標簽,然后拖入紅框中第二個方框內。

Unity <wbr>Steam_VR開發工具插件---VRTK <wbr>自帶案例分析Part1

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM