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。
重要的API:
獲得左右手柄的遊戲物體
VRTK_DeviceFinder.GetControllerRightHand();
VRTK_DeviceFinder.GetControllerLiftHand();
獲得左右手柄對應的硬體編號
VRTK_DeviceFinder.GetControllerIndex(rightHand)
按下手柄任一按鍵或鍵盤上的空格鍵,載入下一個場景。ForwardPressed 用於偵測手柄的按鍵是否按下。
上圖中引入第二個重要的類:VRTK_SDK_Bridge,這是外掛封裝了 SteamVR 的比較底層的API:VRTK_SDK_Bridge.IsTriggerPressedOnIndex(controllerIndex) 。輸入硬體的編號,返回是否按下的布林值。
DEMO 2手柄的輸入事件
封裝成VRTK_ControllerEvent指令碼。針對VR中常見的互動動作: UI點選,抓住物體,觸發物體功能等,自定義手柄按鍵,繫結這些動作。
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所有按鍵的事件,和按鍵的引數資訊。如下圖的扳機鍵的按鍵事件。
事件的引數是:手柄的硬體編號、按鈕的按下程度值(扳機鍵專有的屬性)、 觸控板的觸控位置和角度(觸控板專有的屬性)
DEMO 003_Controller_SimplePointer 傳送位置
VRTK_Simple Pointer類。該指令碼繼承自VRTK_WorldPointer
功能的核心是將玩家的位置傳送到鐳射所指落在的地方,該指令碼應預設放在手柄的prefab上。其他的引數設定啟用顏色、傳送時是否顯示玩家活動區域、鐳射有效觸碰的層、鐳射的粗細等。
DEMO 004_CameraRig_BasicTeleport
VRTK_BasicTeleport。該指令碼配合繼承自VRTK_WorldPointer的子類,如VRTK_Simple Pointer,新增此指令碼後才可以位移傳送。
引數
1)傳送時黑屏:模擬眨眼動畫,過渡更自然。
2)黑屏時間:隨傳送距離遠近成正比的黑屏時間。假如傳送的位置比較遠,則黑屏時間更久。數值越大,黑屏時間越長,數值為0時,不受距離遠近影響。
3)頭部位置:以頭部為基準,作為傳送的位置。未打鉤,則是玩家可玩區域的中心位置作為傳送的目標點。可玩區域不能和遊戲環境交叉,最大化玩家活動空間。
4)禁止傳送物體的標籤:如果傳送的目標位置的物體標籤和此相同,則不能傳送。
5)作為第四個功能的補充:可以新增 VRTK_TagOrScriptPolicyList 指令碼中新增多個禁止傳送的物體標籤。
6)navemesh 邊緣限制:在 navemesh 上傳送,如果在 navemesh 的邊界,則禁止傳送,數值是離邊界的距離範圍。
DEMO 005_Controller_BasicObjectGrabbing
手柄上新增的元件
抓取物體 VRTK_InteractGrab,這個指令碼用來抓取物體,抓的按鍵在 VRTK_ControllerEvent 指令碼中設定。
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:自定義用於判定接觸的剛體物體,如果沒有的話,會自動在子層級建立一個剛體物體。
互動物體上應該新增的指令碼
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打鉤了,則要按住使用按鍵才可以使用該物體。
該指令碼可以 為互動物體增加一個外輪廓顏色。
VRTK_InteractableObject擴充套件
DEMO 006_Controller_UsingADoor
該例子用了一個開門的互動來擴充套件VRTK_InteractableObject 指令碼
接觸VRTK_InteractableObject類,覆蓋開始使用物品的方法,在此方法中寫入互動動作的邏輯方法。此外還有物體被接觸時,抓取時,接觸接觸,結束抓取動作發生時呼叫的函式,可以覆蓋此方法,自定義擴充套件你的互動動作。
注意:手柄上應該新增下圖指令碼,否則無法使用物體
DEMO 007_CameraRig_HeightAdjustTeleport 高度升降傳送
此指令碼繼承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功能類似,不同的是使用拋物線來代替鐳射直線獲取傳送的位置
紅框內是額外的引數, 設定拋物線的最長有效距離, 拋物線 中的物體, 落地的游標物體設定等,沒有什麼額外特別的東西
DEMO 010_CameraRig_TerrainTeleporting地形傳送
此例子沒有演示新的功能,只是展示了可以在地形上傳送
DEMO 011_Camera_HeadSetCollisionFading
頭部碰撞到物品後黑屏眨眼效果,提示玩家已經和遊戲中物體相接觸,讓其返回到正常的區域。附加在Camera(eye) 上
DEMO 012_Controller_PointerWithAreaCollision
傳送的位置附近的物品如果和玩家可活動範圍碰撞器的相接觸,將影響傳送位置的最終位置,使其在合理的範圍內。
開啟可玩區域碰撞體
DEMO 013 演示了多個物體抓取和使用的功能
DEMO 014 演示了抓取物品握住的位置
主要是這裡的引數設定,這些引數的意義之前已經有說明
DEMO 015_Controller_TouchpadAxisControl
演示手指在手柄觸控板的觸控位置vector2 (x,y),來控制小車的移動方向,手柄的扳機,控制小車跳起的動作。基本思路是:一個指令碼監聽手柄的輸入事件, 將事件的相關值傳入到小車的控制器。
監聽手柄按鍵
傳入到小車的控制運動的指令碼
小車的運動部分函式
DEMO 016_Controller_HapticRumble
手柄震動
當藍色盒子上的劍和紅色盒子撞擊時,觸發手柄震動
基本思路是劍的物體碰撞器偵測到碰撞時,獲取手柄的運動速度,來決定震動的強度。
如下圖,controllerAction和ControllerEvents對應的手柄身這兩個指令碼。
關鍵的震動方法是:有VRTK.ControllerAction.TriggerHapticPulse ( 震動強度, 震動持續時間,震動間隔時間)。
DEMO 017_CameraRig_TouchpadWalking
使用觸控板來控制人物行走,以及在低矮的洞穴中蹲走時碰到頭頂的碰撞體,返回到能正常直立站立的位置。附加在此物體上
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 拖到場景中就可以顯示當前幀數
DEMO 019_Controller_InteractingWithPointer
用手柄鐳射和物體互動
VRTK_interactionObject的pointer activates use 打鉤後,就可以用鐳射和物體互動,如果HolonToUse 沒有勾選,那麼鐳射落在物體上,就直接使用該物體。如果HolonToUse勾選了,那就需要啟用指在物體上,同時按下扳機按鍵,才使用物體。
DEMO 020_CameraRig_MeshTeleporting
在各種形狀的網格上傳送
啟用指標傳送和拋物線在複雜網格模型上的傳送效果,沒有新的功能演示
DEMO 021_Controller_GrabbingObjectsWithJoints
物體不同的互動方式
開啟寶箱
盒子的上半部分新增轉軸元件
設定轉軸的轉動軸向,位置,就可以像真實開啟箱子一樣。
箱子的把手需要新增以下指令碼
VRTK_Interactable Object 是必須要新增的指令碼,它保證可以被手柄抓取 rigidbody和fiexed joint是用來連線上半部分的盒子,固定把手的位置
有一定活動區間關節物體
使用character joint 來確定上下關節的連線關係(每個關節也要新增rigidbody 元件)
其關節上的VRTK_InteractableObject 的Grab Attach Mechanic 要設定成spring_joint
該關節互動元件繼承重寫了 抓取和鬆開物體時的方法, 抓取時,剛體模擬動力學運動,鬆開時,就停止模擬,防止受重力影響
抽屜
和開啟盒子相似的設定,不過約束的方式不一樣,用的是configurable joint 注意約束軸向和可活動距離約束數值設定
VRTK_InteractableObject 的抓取方式
DEMO 022_Controller_CustomBezierPointer
自定義拋物線的外觀
DEMO 023_Controller_ChildOfControllerOnGrab
弓箭的思路 抓取方式:作為手柄子物體,跟隨手柄運動
製作弓箭的彎曲動畫
大致思路:
1)手柄抓取弓時,弓的interactableObject 元件查詢是哪個手柄握住弓,得到該手柄的VRTK_ControllerEvents,和VRTK_ControllerActions。前者監聽手柄的輸入,後者控制手柄震動,同理 獲得緩衝拿箭的手柄的這兩個元件。
2)如果當前弓上有箭頭,且手柄握著箭,箭頭位置歸零,箭頭對向瞄準處。拉弦時,弓箭的朝向有拉弦手柄到握弓手柄方向。根據拉弦強度播放拉弓動畫。如果拉弦的手柄鬆開,發射弓箭,初始化弓箭的剛體速度方向。
3)被握住箭碰到弓, 將箭定位到拉弦處的虛擬定位物體的子層級下,箭的方向由拉弦處位置朝向弓把手上箭的放置位置。
DEMO 024_CameraRig_ExcludeTeleportLocations
限制可傳送的物體
在這裡寫入的標籤,無法識別傳送到該物體表面。可以寫入多個標籤,然後拖入紅框中第二個方框內。