Unity3D学习笔记(三十八):VR开发
设备安装: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的