Unity開發VR——插件:HTC.UnityPlugin


插件HTC.UnityPlugin基於SteamVR插件,可以在 Assets Store 搜索HTC.UnityPlugin,免費下載;

使用該插件需要先導入SteamVR插件,也可以在 Assets Store 搜索 SteamVR,免費下載。

HTC.UnityPlugi的優勢:相對於Steamvr來說,方便獲取手柄按鍵、方便與UGUI進行交互

首先

導入SteamVR插件,若SteamVR版本為2.0以上,依次點擊如下按鈕

之后,導入HTC.UnityPlugin插件

PS:HTC.UnityPlugin自帶示例場景位置:HTC.UnityPlugin - ViveInputUtility - Examples - 下級目錄0至7文件夾內,每個文件夾含一個示例

   HTC.UnityPlugin自帶 預 制 體 位置:HTC.UnityPlugin - ViveInputUtility - Prefabs

認識手柄按鍵

VR視角

刪除場景中自帶的Main Camera,將預制體ViveRig拖入大場景中

抓取物體

1. 被抓取的物體需帶有碰撞器

2. 在被抓取的物體上添加腳本 BasicGrabbable

PS:物體B、C、D、E……是物體A的父物體

 物體A掛載腳本BasicGrabbable,子物體不掛載該腳本

移動 B、C、D、E……任何一個物體,物體A下的所以子物體均會同步移動

物體A掛載腳本BasicGrabbable,子物體也掛載該腳本

只有在移動物體A時,物體A下的所以子物體才會同步移動,移動其中一個子物體時,其父物體和其余子物體不會跟着移動

   若需要物體在放手之后做物理運動,則需要給物體添加Rigidbody組件

   若需要拿起物體之后隱藏手部模型,需要給腳本BasicGrabbable賦值,並選擇方法,如下圖:

  

       PS:獲得射線檢測到的物體

玩家移動

1. 在要移動的地面上添加腳本Teleportable,賦值方法如下:

   

 

2. 運行程序,按住TouchPad出現釣魚線;松開按鍵后移動到釣魚線落下的位置

PS:將可以移動的區域放在同一個父物體下,給這個父物體添加Teleportable腳本,那么這些區域就都可以移動。

射線移動物體

1. 將預制體 VivePointers 拖入場景中,作為ViveRig的子物體,並把TransFrom Rest;

2. 在被移動的物體上添加腳本 Draggable。

射線點擊UGUI

  1. 射線出現的方式

(1)按 Menu 鍵會出現與UI交互的射線,但此時手柄碰撞器消失,不能進行碰撞檢測;再次按 Menu 鍵,與UI交互的射線消失,此時手柄可以進行碰撞檢測;

(2)將預制體 VivePointers 拖入場景中,作為ViveRig的子物體,並把TransFrom Rest,射線會一直出現,並且手柄也可以進行射線檢測;

2. 創建一個UI,如:Button;

3. 在Canvas面板添加腳本 CanvasRaycastTarget;

4. 刪除場景中的游戲物體“EventSystem”(經測試不刪也沒有問題,但是在運行時程序會自動創建一個 EventSystem ,最好還是刪掉)。

替換手柄模型

1. 設置預制體屬性:ViveRig - ViveControllers - Right - RenderModel - DeviceTracker - OpenVRRenderModel 的腳本“RenderModelHook”,將 OverrideModel 設置為 IndexHMD(OverrideModel中有多種模型可供選擇,可以在運行情況下嘗試)

2. 把要替換的模型作為OpenVRRenderModel的子物體(如果第一步不選擇IndexHMD,那么要替換的模型會和手柄模型一起出現)

設置釣魚線

以右手為例:

線:ViveRig - ViveControllers - Right - CurvePointer - GuideLine

落地點:ViveRig - ViveControllers - Right - CurvePointer - Reticle - Puramid - default

可通過上述屬性,設置釣魚線的材質、網格

設置釣魚線的遠近:ViveRig - ViveControllers - Right - CurvePointer - StablizedDeviceTracker - Caster 的腳本“ProjectileGenerator”的屬性:Velocity

替換UI交互射線

相對於預制體:VivePointers

射線的位置:VivePointers - Right - Reticle - GuideLine

終點小球的位置:VivePointers - Right - Reticle - Sphere - Mesh

終點小球的材質:VivePointers - Right - Reticle 的腳本 ReticlePoser 的屬性 DefaultReticleMat 

可通過上述屬性,設置釣魚線的材質、網格

相對於預制體:ViveRig

射線的位置:ViveRig - ViveControllers - Right - Laser Pointer - Reticle - GuideLine

終點小球的位置:ViveRig - ViveControllers - Right - Laser Pointer - Reticle - Sphere - Mesh

可通過上述屬性,設置釣魚線的材質、網格

得到手柄按鍵

可以復制代碼到工程中進行測試,自行領會;注意,腳本名和類名一致:TestHandKey

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 引入該命名空間
using HTC.UnityPlugin.Vive;

public class TestHandKey : MonoBehaviour
{
    // 給按鍵添加事件(以 Menu 為例)
    private void Awake()
    {
#if false

        // 按住不放:右手的 Menu鍵 調用方法一
        ViveInput.AddPress(HandRole.RightHand, ControllerButton.Menu, One);
        // 按下:右手的 Menu鍵 調用方法二
        ViveInput.AddPressDown(HandRole.RightHand, ControllerButton.Menu, Two);
        // 點擊:右手的 Menu鍵 調用方法三(點擊:按下之后立刻抬起才會響應,按住不放 一段時間后再放開,則不會調用)
        ViveInput.AddClick(HandRole.RightHand, ControllerButton.Menu, Three);

#endif
    }

    // 方法一
    private void One()
    {
        print("調用了 方法一");
    }

    // 方法二
    private void Two()
    {
        print("調用了 方法二");
    }

    // 方法三
    private void Three()
    {
        print("調用了 方法三");
    }

    // 測試按鍵的按下、按住、抬起
    private void Update()
    {
#if false // 打印 Trigger 的返回值 print("Trigger的返回值為:" + ViveInput.GetTriggerValue(HandRole.RightHand, false)); // 打印 Pad 的坐標值 print("Pad的坐標:" + ViveInput.GetPadAxis(HandRole.RightHand, false)); #endif #if true // Menu if (ViveInput.GetPressDown(HandRole.RightHand, ControllerButton.Menu)) { print("右手 - Menu - 按下"); } else if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.Menu)) { print("右手 - Menu - 按住不放"); } else if (ViveInput.GetPressUp(HandRole.RightHand, ControllerButton.Menu)) { print("右手 - Menu - 抬起"); } // Trigger if (ViveInput.GetPressDown(HandRole.RightHand, ControllerButton.Trigger)) { print("右手 - Trigger - 按下"); } else if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.Trigger)) { print("右手 - Trigger - 按住不放"); } else if (ViveInput.GetPressUp(HandRole.RightHand, ControllerButton.Trigger)) { print("右手 - Trigger - 抬起"); } // pad(是否觸摸到pad,通過判斷GetPadAxis的返回時是否是(0,0)來判斷) if (ViveInput.GetPressDown(HandRole.RightHand, ControllerButton.Pad)) { print("右手 - Pad - 按下"); } else if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.Pad)) { print("右手 - Pad - 按住不放"); } else if (ViveInput.GetPressUp(HandRole.RightHand, ControllerButton.Pad)) { print("右手 - Pad - 抬起"); } // Grip if (ViveInput.GetPressDown(HandRole.RightHand, ControllerButton.Grip)) { print("右手 - Grip - 按下"); } if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.Grip)) { print("右手 - Grip - 按住不放"); } if (ViveInput.GetPressUp(HandRole.RightHand, ControllerButton.Grip)) { print("右手 - Grip - 抬起"); } #endif #if false // Trigger 輕按、重按、按到底 if (ViveInput.GetPressDown(HandRole.RightHand, ControllerButton.HairTrigger)) { print("Trigger - 輕按"); } else if (ViveInput.GetPressDown(HandRole.RightHand, ControllerButton.Trigger)) { print("Trigger - 重按"); } else if (ViveInput.GetPressDown(HandRole.RightHand, ControllerButton.FullTrigger)) { print("Trigger - 按到底"); } #endif #if false // GetPadTouchAxis:觸摸 就會返回坐標值 print(ViveInput.GetPadTouchAxis(HandRole.RightHand)); // 從左向右滑,橫坐標為正; 從右向左滑,橫坐標為負; 從下向上滑,縱坐標為正; 從上向下滑,縱坐標為負 print(ViveInput.GetPadTouchDelta(HandRole.RightHand)); // GetPadTouchVector:以開始觸摸點為(0,0),若觸摸點為pad的最下方,當手指滑到最上方時坐標值為(0,2) print(ViveInput.GetPadTouchVector(HandRole.RightHand)); // GetPadTouchAxis 為觸摸反饋;GetPadPressAxis 為按住反饋 print(ViveInput.GetPadPressAxis(HandRole.RightHand)); print(ViveInput.GetPadPressDelta(HandRole.RightHand)); print(ViveInput.GetPadPressVector(HandRole.RightHand)); #endif } }

 

 


免責聲明!

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



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