1. 程式人生 > >Unity Steam_VR 開發工具外掛 VRTK自帶案例分析(第一部分)

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

轉至https://www.cnblogs.com/zerotoinfinity/p/6474840.html

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_SimplePointer 傳送位置

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