設備安裝:HTC View
驅動安裝:Steam - SteamVR

設備激活
Unity開發
下載安裝開發包
Asset Store - SteamVR Plugin

SteamVRDemo1-鏡頭
SteamVRDemo2-交互場景

Demo1-交互基礎部分
手柄按鍵
正面:
----系統
----觸控盤(半徑為1的二維坐標)
----手柄開關(單擊激活,長按關閉)
側面:
----側面按鍵
背面:
----扳機鍵
場景攝像頭設置
Camera添加SteamVR組件,即可完成頭戴攝像機功能

按鍵輸入設置
手部設備

代碼邏輯
創建枚舉類型,區分左右手柄
雙手武器,需要獲取另外一只手的引用
/// <summary> /// 手柄類型 用於初始化手柄設備 /// </summary> public HandType handType = HandType.LeftHand; // 手上拿的武器是單手還是雙手的 public ItemPackage.ItemPackageType itemType = ItemPackage.ItemPackageType.OneHanded; public HandDevice otherHand = null; /// <summary> /// 控制手柄的設備 /// </summary> public SteamVR_Controller.Device controller;
SteamVR_Controller類
通用按鍵(通過枚舉類型和鍵值控制相應按鍵)
public bool GetPress(ulong buttonMask) { Update(); return (state.ulButtonPressed & buttonMask) != 0; } public bool GetPressDown(ulong buttonMask) { Update(); return (state.ulButtonPressed & buttonMask) != 0 && (prevState.ulButtonPressed & buttonMask) == 0; } public bool GetPressUp(ulong buttonMask) { Update(); return (state.ulButtonPressed & buttonMask) == 0 && (prevState.ulButtonPressed & buttonMask) != 0; } public bool GetPress(EVRButtonId buttonId) { return GetPress(1ul << (int)buttonId); } public bool GetPressDown(EVRButtonId buttonId) { return GetPressDown(1ul << (int)buttonId); } public bool GetPressUp(EVRButtonId buttonId) { return GetPressUp(1ul << (int)buttonId); }
觸控盤(方法,枚舉,軸值)
public bool GetTouch(ulong buttonMask) { Update(); return (state.ulButtonTouched & buttonMask) != 0; } public bool GetTouchDown(ulong buttonMask) { Update(); return (state.ulButtonTouched & buttonMask) != 0 && (prevState.ulButtonTouched & buttonMask) == 0; } public bool GetTouchUp(ulong buttonMask) { Update(); return (state.ulButtonTouched & buttonMask) == 0 && (prevState.ulButtonTouched & buttonMask) != 0; } public bool GetTouch(EVRButtonId buttonId) { return GetTouch(1ul << (int)buttonId); } public bool GetTouchDown(EVRButtonId buttonId) { return GetTouchDown(1ul << (int)buttonId); } public bool GetTouchUp(EVRButtonId buttonId) { return GetTouchUp(1ul << (int)buttonId); } public Vector2 GetAxis(EVRButtonId buttonId = EVRButtonId.k_EButton_SteamVR_Touchpad) { Update(); var axisId = (uint)buttonId - (uint)EVRButtonId.k_EButton_Axis0; switch (axisId) { case 0: return new Vector2(state.rAxis0.x, state.rAxis0.y); case 1: return new Vector2(state.rAxis1.x, state.rAxis1.y); case 2: return new Vector2(state.rAxis2.x, state.rAxis2.y); case 3: return new Vector2(state.rAxis3.x, state.rAxis3.y); case 4: return new Vector2(state.rAxis4.x, state.rAxis4.y); } return Vector2.zero; }
震動方法,只有觸控盤和側面按鍵有
public void TriggerHapticPulse(ushort durationMicroSec = 500, EVRButtonId buttonId = EVRButtonId.k_EButton_SteamVR_Touchpad) { var system = OpenVR.System; if (system != null) { var axisId = (uint)buttonId - (uint)EVRButtonId.k_EButton_Axis0; system.TriggerHapticPulse(index, axisId, (char)durationMicroSec); } }
扳機鍵(方法,枚舉,軸值)
public float hairTriggerDelta = 0.1f; // amount trigger must be pulled or released to change state float hairTriggerLimit; bool hairTriggerState, hairTriggerPrevState; void UpdateHairTrigger() { hairTriggerPrevState = hairTriggerState; var value = state.rAxis1.x; // trigger if (hairTriggerState) { if (value < hairTriggerLimit - hairTriggerDelta || value <= 0.0f) hairTriggerState = false; } else { if (value > hairTriggerLimit + hairTriggerDelta || value >= 1.0f) hairTriggerState = true; } hairTriggerLimit = hairTriggerState ? Mathf.Max(hairTriggerLimit, value) : Mathf.Min(hairTriggerLimit, value); } public bool GetHairTrigger() { Update(); return hairTriggerState; } public bool GetHairTriggerDown() { Update(); return hairTriggerState && !hairTriggerPrevState; } public bool GetHairTriggerUp() { Update(); return !hairTriggerState && hairTriggerPrevState; }
側面按鍵(枚舉)
Demo2-交互升級部分-射擊
private void InputDebug() { if (controller == null) return; // 按扳機鍵 if (controller.GetPressDown(EVRButtonId.k_EButton_SteamVR_Trigger) || controller.GetPressDown(EVRButtonId.k_EButton_Axis1)) { Debug.Log("按下扳機鍵"); GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere); obj.transform.localScale = Vector3.one * 0.1f; obj.transform.position = transform.position; Rigidbody rig = obj.AddComponent<Rigidbody>(); rig.AddForce(transform.forward * 400f); Destroy(obj, 2f); } //if (controller.GetTouch(EVRButtonId.k_EButton_Axis0)) //{ // Debug.Log("接觸了觸控盤"); //} if (controller.GetPressDown(EVRButtonId.k_EButton_SteamVR_Touchpad) || controller.GetPressDown(EVRButtonId.k_EButton_Axis0)) { Debug.Log("按下觸控盤"); } // 獲得觸控盤軸值 軸值在半徑為1的圓上 Vector2 touchPad = controller.GetAxis(); if (touchPad != Vector2.zero) { Debug.Log("touchPad : " + touchPad); GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere); obj.transform.localScale = Vector3.one * 0.01f; obj.transform.position = new Vector3(touchPad.x, 0, touchPad.y); } if (controller.GetPressDown(EVRButtonId.k_EButton_Grip)) { Debug.Log("Grip...側面按鍵被按下"); StartCoroutine(TriggerHapticPulse()); } }
VR界面UI
世界坐標系,畫布渲染模式改成世界空間
UI都需要改成3D的
