VRTK使用
參考文檔:https://blog.csdn.net/qq_25601345/article/details/78497537?tdsourcetag=s_pcqq_aiomsg#_Toc31475
VRTK:3.2.1 版本 Steam VR:Assets Store下載
1、手柄發射射線
- 手柄控制器掛載兩個腳本:VRTK_Pointer 射線發射腳本 和 VRTK_Stratight Pointer Renderer
直
射線渲染腳本(或 VRTK_Bezier Pointer Renderer曲
射線腳本組件,射線的模型和目標點模型等參數可自定義),VRTK_Pointer腳本中指定Pointer Render類型;
2、手柄基本交互事件(觸摸、抓取和使用)
給手柄控制器添加 VRTK_Controller_Events 腳本(手柄事件機制必需);
- 根據需要添加以下腳本組件 :
VRTK_Interact Touch(觸碰)
VRTK_Interact Grab(抓取注:指定默認的抓取按鍵 Grab Button
)
VRTK_Interact Use(使用注:指定默認的使用按鍵 Use Button
)
一般 Events、Touch、Grab、Use 這幾個腳本都給控制器添加上
抓取和使用腳本中,按鈕若指定默認值,被交互物體所掛腳本中按鈕可默認不更改;按鈕若不指定,被交互物體所掛腳本中按鈕要自定義;否則,被交互物體不能響應手柄的事件
3、物體抓取
- 物體能夠被抓取的條件*
需要有Rigidbody
和Collider
組件,
掛載 VRTK_Interactable Object 腳本纔可以響應手柄的交互,Touch Highlight Color 調整觸碰時的高亮顏色,
如果不給物體添加抓取方式,默認使用固定關節抓取方式:VRTK_FixedJointGrabAttach,
掛載VRTK_ Outline Object Copy Highlighter腳本使物體 外輪廓 呈現高亮,默認整體高亮
注:
- VRTK_Interactable Object腳本中的 Is Grabable(Is Usable) 默認是不勾選的,如果想要該物體能夠被抓取,需要勾選該選項
- 如果想點擊抓取按鈕之後就拿到物體,而不是一直按着按鈕,取消勾選 Hold Button To Grab 即可
- 掛載 VRTK_Swap Controller Grab Actions 腳本實現物體可以左右手交換
七種抓取方式:
VRTK_FixedJointGrabAttach 固定關節抓取(系統默認方式)
VRTK_SpringJointGrabAttach 彈簧關節抓取(手柄和被抓取物體之間彈簧鏈接效果,比如抽屜的彈性效果)
VRTK_CustomJointGrabAttach 自定義關節抓取(添加所需類型的Joint組件,並指定給自定義關節參數 Custom Joint)
VRTK_TrackObjectGrabAttach 對象追蹤抓取(被抓取物體跟蹤手柄,受外力阻擋時不會掉落)
VRTK_ClimbableGrabAttach 可攀爬抓取(實現手抓物體可攀爬效果),另外需要在場景上掛載 VRTK_Player Climb 腳本
VRTK_RotatorTrackGrabAttach 旋轉體抓取 (效果和彈簧關節相似,比如門旋轉的彈性效果,筆者猜測鐘擺效果也可)
VRTK_ChildOfControllerGrabAttach 作爲控制器子物體(抓取物體成爲手柄控制器模型子物體,射箭的典型例子)
4、物體使用(第25個例子未研究,一些物體的使用)
手柄控制器添加 VRTK_Interact Use 腳本,
被使用物體添加自定義腳本,繼承VRTK_Interactable Object 類(勾選 Is Usable),重寫該類的 StartUsing () { //自定義“使用”功能 } 和 StopUsing () 方法
注:
- 若多個物體組成被交互對象,其中有使用對象,腳本掛在父容器上即可
射線使用物體:
勾選 Use Options 中的 Pointer Activates Use 實現
5、物體交互手柄震動
TriggerHapticPulse() 函數實現手柄震動:
- 參數:
index:手柄索引
strength:震動強度
duration:持續時間
舊版本VRTK中使用的是 VRTK_Controller Action.TriggerHapticPulse(float strength);
較新版本中使用的是 VRTK_SharedMethods.TriggerHapticPulse
( int index ,float strength,float duration);
以上兩種方法逐漸被棄用,使用 VRTK_ControllerHaptics.TriggerHapticPulse(controllerReference, 5000f);
//最簡單的手柄碰撞震動腳本,腳本掛載Stick物體上,VRTK_ChildOfControllerGrabAttach 抓取方式
public class Stick : VRTK_InteractableObject{
//控制器引用(即 Left/RightCntroller)
private VRTK_ControllerReference controllerReference;
public override void Grabbed(VRTK_InteractGrab currentGrabbingObject = null)
{
base.Grabbed(currentGrabbingObject);
//獲取當前抓取物體的控制器
controllerReference = VRTK_ControllerReference.GetControllerReference(currentGrabbingObject.controllerEvents.gameObject);
}
public override void Ungrabbed(VRTK_InteractGrab previousGrabbingObject = null)
{
base.Ungrabbed(previousGrabbingObject);
controllerReference = null;
}
private void OnCollisionEnter(Collision collision)
{
if (VRTK_ControllerReference.IsValid(controllerReference) && IsGrabbed())
{
//手柄震動函數
VRTK_ControllerHaptics.TriggerHapticPulse(controllerReference, 5000f);
}
}
}
6、TouchPad 控制主角移動、添加自定義菜單
1、手柄控制器上掛載 VRTK_Touchpad Control 腳本組件控制圓盤
- 參數說明:
Device For Direction:選擇哪個設備的方向爲準
Disable Other Controllers On Active:如果勾選,將其他監聽TouchPad事件的函數都禁用掉
Affect On Falling:當下落的時候可以繼續控制
Primary Activation Button:哪個按鈕啓動控制
Active Modifier Button:激活控制行爲的按鈕
- 真正實現圓盤控制主角移動,還需要 VRTK_SlideObjectControl Action 腳本設置軸偏移量,並且要指定 Object Controller Scripts
Maximum Speed :觸摸 TouchPad 時最大移動速度
Speed Multilier:TouchPad 按下時速度倍乘
2、RadialMenu 預製體,VRTK_Radial Menu 菜單設置腳本 和 VRTK_Radial Menu Controller 菜單控制腳本
- VRTK_Radial Menu 參數說明:
Buttons:設置按鈕數量,內部元素設置按鈕的 圖片樣式 和 添加事件監聽
Button Prefab:按鈕面板的樣式(默認環形)
Button Thickness:環的寬度
Offset Distance:按鈕間距
Offset Rotation:按鈕旋轉的方位角
Rotate Icons:是否旋轉菜單圖標來適應菜單朝向
Icon Margin:圖標到邊緣距離
Hide On Release:釋放時隱藏
Execute On Unclick:釋放按鈕時是否執行事件
Base Haptic Strength:選擇不同按鈕時的震動
7、對象排除/包含列表 (VRTK_Policy List)
以瞬移爲例,如下圖
VRTK_Policy List 屬性解析:
- Operation爲Ignore/Include(忽略),Types爲Tag(標籤)和Script(腳本)等,Element裏面設置了ExcludeTeleport,這樣設置,如果遊戲物體上掛載有 ExcludeTeleport 這個名稱的腳本或是遊戲物體的標籤爲ExcludeTeleport,都不能瞬移到這個遊戲物體上
- 舉個栗子,現在要在一個房間中實現瞬移,並且你想限制只能夠在地板上瞬移,不能瞬移到高處,比如桌子、櫃子上什麼的;此時添加 Policy List 腳本,Operation選擇 Include 地板 ground,或者 Operation 選擇 Ignore 除地板之外的所有物體
8、射線與UI交互 (VRTK_UI Pointer、VRTK_UI Canvas)
注:實現射線與UI交互,需要給控制器添加 VRTK_UI Pointer 腳本
三種UI交互方式:
- 普通UGUI:Canvas 的Render Mode設置爲 World Space ;掛載腳本 VRTK_UICanvas
- 鍵盤UI:添加腳本 VRTK_UICanvas 和 UI_KeyBoard ,在每個按鍵Button上要綁定點擊事件 ClickKey
UI_KeyBoard 腳本即控制鍵盤輸入的代碼:
public class UI_Keyboard : MonoBehaviour
{
private InputField input; //輸入框
private void Start()
{ //獲取輸入框組件
input = GetComponentInChildren<InputField>();
}
//點擊鍵盤上的字母時執行
public void ClickKey(string character)
{
input.text += character;
}
//點擊空格時執行
public void Backspace()
{ //如果輸入文本長度不爲零
if (input.text.Length > 0)
{ //文本分割,去掉最後一位
input.text = input.text.Substring(0, input.text.Length - 1);
}
}
//點擊Enter鍵時執行
public void Enter()
{ //提示語
VRTK_Logger.Info("You've typed [" + input.text + "]");
//輸入框文本清空
input.text = "";
}
}
- 拖拽UI:添加腳本 VRTK_UIDropZone
9、瞬移
- 四種瞬移方式:
VRTK_Basic Teleport :基本的瞬移
VRTK_Height Adjust Teleport :高度適應的瞬移,繼承基本瞬移的功能
VRTK_Dash Teleport :模擬過程的瞬移,繼承基本瞬移和高度適應的瞬移
VRTK_Transform Follow :頭盔決定瞬移目標點
1、基本瞬移:場景中掛載腳本 VRTK_Basic Teleport 實現
掛載 VRTK_Dash Teleport 腳本,可以優化瞬移效果,不是硬生生的出現在目標點,而是像衝過去一樣
2、適應高度的瞬移:場景中掛載腳本 VRTK_Height Adjust Teleport 實現
3、模擬過程的瞬移:場景中掛載腳本 VRTK_Basic Teleport 實現
4、頭盔確定目標點的瞬移
- 創建空對象,命名TransForm Follower(自定義),掛載 VRTK_SDK Object Alias 腳本,參數選擇 HeadSet 也就是跟隨對象選擇頭盔
- 創建空對象,命名HeadSet(自定),掛載 VRTK_Pointer、VRTK_Bezier Pointer Renderer 和 VRTK_Transform Follow 腳本,前兩個腳本實現發射曲射線,後者Follow實現射線跟隨頭盔,並且改變頭盔的位置(即實現瞬移)
Pointer 要自定義手柄控制器,也就是使用哪個手柄觸發頭盔瞬移
筆者測試,用曲線實現此種瞬移比較好;如果選用直射線,射線有角度變化,目標點光標會變形
可以根據需要自行選擇光標的形狀、光標和射線路徑是否顯示
要特別注意 Transform Follow 中的賦值
10、雙手操作
-
VRTK_MoveInPlace 腳本掛載到場景中,原地踏步就能實現移動,方向控制還需晃動頭部,要是有萬向走步機就更好了。
-
雙手同時操作物體
1、VRTK_AxisScaleGrabAction 腳本實現雙手縮放物體
2、VRTK_ControlDirectionGrabAction 腳本實現雙手同時拿起同一個物體,一般是長物體
11、射線作爲手柄擴展
- VRTK_Pointer 腳本組件中的 Interact With Objects 屬性:如果勾選該屬性,那麼射線就相當於手柄控制器的擴展;已知只有當手柄接觸到物體時,纔會有高亮顯示(如果你想),若實現手柄接觸物體也能高亮顯示,需勾選該選項,讓射線代替手柄去接觸物體即可實現,,,當然被選中物體要有Interactable Object 腳本,且勾選Pointer Active Use 的選項
12、獲取手柄按鍵
//獲取右手手柄的引用
rightControllerReference = VRTK_ControllerReference.GetControllerReference(VRTK_DeviceFinder.GetControllerRightHand(true));
//獲取手指是否觸摸手柄圓盤,返回Bool值
isTouchPadTouch = VRTK_SDK_Bridge.GetControllerButtonState(SDK_BaseController.ButtonTypes.Touchpad, SDK_BaseController.ButtonPressTypes.Touch, rightControllerReference);
isTouchPadUp = VRTK_SDK_Bridge.GetControllerButtonState(SDK_BaseController.ButtonTypes.Touchpad, SDK_BaseController.ButtonPressTypes.TouchUp, rightControllerReference);