标签:
本章节主要讲解使用SteamVR Plugins插件为基础,来介绍Vive开发的入门,重点讲解设备的激活和控制接口。SteamVR Plugins在unity官方资源商店可以免费下载,这里我就不给出链接了。
导入SteamVR Plugins后,不要在他的示例上去做开发,那样你会走弯路。因为这个插件的设备初始化代码很怪异,甚至可以说无法使用。因此我们需要自己写设备的初始化代码以及设备的操作接口。
我们对原插件进行封装后就可以愉快的使用了,之后怎么开发就和这个设备无关了,我们开发这类的应用无非是获取相关的接口操作。
新建场景,然后在Camera上添加组件SteamVR_Camera,然后点击 Expand 按钮,之后我们就得到了一个基本的VR相机。
然后我们在Camera的下面新建两个GameObject,并命名为LeftHand和RightHand。同时添加组件SteamVR_TrackedObject。然后在各自的下面添加一个对象名为Mode,并绑定组件SteamVR_RenderModel。
如果对这些步骤有疑问,可以查看百度文库按照上面的操作完成基本的对象搭建操作:http://wenku.baidu.com/view/eaaec2f058fb770bf68a55b1.html
接下来就是开始撸代码了,新建脚本SteamVR_InitManager.cs,来获取手柄的激活和相关的初始化代码。
using UnityEngine;
using System.Collections;
using Valve.VR;
using System;
public class SteamVR_InitManager : MonoBehaviour
{
public event Action<SteamVR_TrackedObject> OnLeftDeviceActive;//左手柄激活事件
public event Action<SteamVR_TrackedObject> OnRightDeviceActive;//右手柄激活事件
public SteamVR_TrackedObject LeftObject;
public SteamVR_TrackedObject RightObject;
private bool[] isAllConnect;//0代表右手状态,1代表左手状态
private uint leftIndex = 100;//左手柄对应的设备ID
private uint rightIndex = 100;//右手柄对应的设备ID
private static SteamVR_InitManager instance;
public DeviceInput LeftHandInput;
public DeviceInput RightHandInput;
public static SteamVR_InitManager Instance {
get {
if (instance == null) {
instance = GameObject.FindObjectOfType<SteamVR_InitManager>();
}
return instance;
}
}
// Use this for initialization
void Awake()
{
LeftObject = transform.FindChild("LeftHand").GetComponent<SteamVR_TrackedObject>();
RightObject = transform.FindChild("RightHand").GetComponent<SteamVR_TrackedObject>();
LeftObject.gameObject.SetActive(false);
RightObject.gameObject.SetActive(false);
}
void Start()
{
StartCoroutine(CheckDeviceActive());
}
void OnEnable()
{
OnLeftDeviceActive += LeftDeviceActive;
OnRightDeviceActive += RightDeviceActive;
}
void OnDisable()
{
OnLeftDeviceActive -= LeftDeviceActive;
OnRightDeviceActive -= RightDeviceActive;
}
/// <summary>
/// 检测手柄设备是否激活
/// </summary>
/// <returns></returns>
IEnumerator CheckDeviceActive()
{
yield return new WaitForSeconds(1);
while (!isAllConnect[0] || !isAllConnect[1])
{
for (uint i = 1; i < OpenVR.k_unMaxTrackedDeviceCount; i++)
{
if (i == leftIndex || i == rightIndex) continue;//已经初始化的不再进入判断
if (OpenVR.System != null && OpenVR.System.IsTrackedDeviceConnected(i))
{
OnDeviceConnected(new object[] { i, true });
}
}
yield return new WaitForFixedUpdate();
}
yield return 0;
}
/// <summary>
/// 检测激活的设备是否是手柄
/// </summary>
/// <param name="args"></param>
private void OnDeviceConnected(object[] args)
{
if (args != null && args.Length > 1)
{
uint index = (uint)args[0];
bool isConnect = (bool)args[1];
var system = OpenVR.System;
if (isConnect && system != null && system.GetTrackedDeviceClass(index) == ETrackedDeviceClass.Controller)
{
uint tmpleftIndex = (uint)system.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole.LeftHand);
uint tmprightIndex = (uint)system.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole.RightHand);
if (index == tmprightIndex)
{
isAllConnect[0] = true;
rightIndex = index;
OnRightDeviceActive(RightObject);
}
else if (index == tmpleftIndex)
{
isAllConnect[1] = true;
leftIndex = index;
OnLeftDeviceActive(LeftObject);
}
}
}
}
private void RightDeviceActive(SteamVR_TrackedObject obj)
{
DeviceActive(obj, rightIndex);
RightHandInput = obj.GetComponent<DeviceInput>();
}
private void LeftDeviceActive(SteamVR_TrackedObject obj)
{
DeviceActive(obj, leftIndex);
LeftHandInput = obj.GetComponent<DeviceInput>();
}
/// <summary>
/// 匹配对应的设备号,完成手柄模型的设置
/// </summary>
/// <param name="device"></param>
/// <param name="index"></param>
void DeviceActive(SteamVR_TrackedObject device, uint index)
{
SteamVR_TrackedObject.EIndex eIndex = (SteamVR_TrackedObject.EIndex)Enum.Parse(typeof(SteamVR_TrackedObject.EIndex), "Device" + index);
device.index = eIndex;
device.GetComponentInChildren<SteamVR_RenderModel>().index = eIndex;
device.gameObject.SetActive(true);
}
}
然后就是大家比较关心的手柄控制接口代码DeviceInput.cs,我基本上把所有的手柄控制事件都写完了.
using UnityEngine;
using System.Collections;
using System;
using Valve.VR;
public class DeviceInput : MonoBehaviour {
//Swipe directions
public enum SwipeDirection
{
NONE,
UP,
DOWN,
LEFT,
RIGHT
};
public event Action OnPressTrigger; //按住扳机键
public event Action OnPressDownTrigger; // 按下扳机键
public event Action OnPressUpTrigger; //抬起扳机键
public event Action OnTouchPad; //按住触摸板
public event Action OnPressDownGripButton; //按下侧键
public event Action OnPressDownMenuButton; //按下菜单键
public event Action<Vector2> OnBeginTouch; //触摸触摸板的位置
public event Action<Vector2> OnEndTouch;//抬起触摸板的位置
public event Action OnTouchPadDown; //按下触摸板
public event Action OnTouchPadUp;//抬起触摸板
public event Action<SwipeDirection> OnPadSwipe;
[SerializeField]
private float m_SwipeWidth = 0.6f; //The width of a swipe
private Vector2 m_PadDownPosition;
private float m_LastHorizontalValue;
private float m_LastVerticalValue;
private SteamVR_TrackedObject Hand;
private SteamVR_Controller.Device device;
private Vector2 m_PadPosition;
public void Start()
{
Hand = GetComponent<SteamVR_TrackedObject>();
}
public void Update()
{
CheckInput();
}
private void CheckInput()
{
// Set the default swipe to be none.
SwipeDirection swipe = SwipeDirection.NONE;
if (device == null)
{
device = SteamVR_Controller.Input((int)Hand.index);
print("NUll Device");
return;
}
if (device.GetPress(EVRButtonId.k_EButton_SteamVR_Trigger))
{
if (OnPressTrigger != null) OnPressTrigger();
}
if (device.GetPressDown(EVRButtonId.k_EButton_SteamVR_Trigger))
{
if (OnPressDownTrigger != null) OnPressDownTrigger();
}
if (device.GetPressUp(EVRButtonId.k_EButton_SteamVR_Trigger))
{
if (OnPressUpTrigger != null) OnPressUpTrigger();
}
if (device.GetTouch(EVRButtonId.k_EButton_SteamVR_Touchpad))
{
if (OnTouchPad != null) OnTouchPad();
m_PadPosition = device.GetAxis();
}
if (device.GetTouchUp(EVRButtonId.k_EButton_SteamVR_Touchpad))
{
if (OnTouchPadUp != null) OnTouchPadUp();
if (OnEndTouch != null) OnEndTouch(m_PadPosition);
swipe = DetectSwipe();
m_PadDownPosition = Vector2.zero;
}
if (device.GetTouchDown(EVRButtonId.k_EButton_SteamVR_Touchpad))
{
if (OnTouchPadDown != null) OnTouchPadDown();
if (OnBeginTouch != null) OnBeginTouch(m_PadDownPosition = device.GetAxis());
}
if (device.GetPressDown(EVRButtonId.k_EButton_Grip))
{
if (OnPressDownGripButton != null) { OnPressDownGripButton(); }
}
if (device.GetPressDown(EVRButtonId.k_EButton_ApplicationMenu))
{
if (OnPressDownMenuButton != null) OnPressDownMenuButton();
}
if (swipe != SwipeDirection.NONE)
{
OnPadSwipe(swipe);
if (device.GetTouch(EVRButtonId.k_EButton_SteamVR_Touchpad))
{
m_PadPosition = device.GetAxis();
}
else {
m_PadDownPosition = Vector2.zero;
}
}
}
private SwipeDirection DetectSwipe()
{
Vector2 swipeData = (m_PadPosition - m_PadDownPosition).normalized;
bool swipeIsVertical = Mathf.Abs(swipeData.y) > m_SwipeWidth;
bool swipeIsHorizontal = Mathf.Abs(swipeData.x) > m_SwipeWidth;
if (swipeData.y > 0f && swipeIsVertical)
return SwipeDirection.UP;
if (swipeData.y < 0f && swipeIsVertical)
return SwipeDirection.DOWN;
if (swipeData.x > 0f && swipeIsHorizontal)
return SwipeDirection.RIGHT;
if (swipeData.x < 0f && swipeIsHorizontal)
return SwipeDirection.LEFT;
return SwipeDirection.NONE;
}
public void OnDisEnable()
{
OnPressTrigger = null; //按住扳机键
OnPressDownTrigger = null; // 按下扳机键
OnPressUpTrigger = null; //抬起扳机键
OnTouchPad = null; //按住触摸板
OnPressDownGripButton = null; //按下侧键
OnPressDownMenuButton = null; //按下菜单键
OnBeginTouch = null; //触摸触摸板的位置
OnEndTouch = null;//抬起触摸板的位置
OnTouchPadDown = null; //按下触摸板
OnTouchPadUp = null;//抬起触摸板
OnPadSwipe = null;
}
}
OK,接下来写一个简单的测试类来测试相关的代码:
using UnityEngine;
using System.Collections;
using System;
/// <summary>
/// 这是一个测试类,简单的测试了手柄的激活以及部分手柄的操作事件
/// 两个手柄分开注册,这样扩展性非常好,相同的按键可以做不同的处理
/// 大家可以补充测试
/// </summary>
public class TestEvent : MonoBehaviour {
void OnEnable() {
SteamVR_InitManager.Instance.OnLeftDeviceActive += OnLeftDeviceActive;//左手柄激活
SteamVR_InitManager.Instance.OnRightDeviceActive += OnRightDeviceActive;//右手柄激活
}
private void OnRightDeviceActive(SteamVR_TrackedObject obj)
{
print("OnRightDeviceActive"+obj);
SteamVR_InitManager.Instance.RightHandInput.OnPressDownTrigger += OnPressDownTrigger;
SteamVR_InitManager.Instance.RightHandInput.OnTouchPadDown += OnTouchPadDown;
}
private void OnPressDownTrigger()
{
print("OnPressDownTrigger");
}
private void OnTouchPadDown()
{
print("OnTouchPadDown");
}
private void OnLeftDeviceActive(SteamVR_TrackedObject obj)
{
print("OnLeftDeviceActive" + obj);
SteamVR_InitManager.Instance.LeftHandInput.OnPressDownTrigger += OnPressDownTrigger;
SteamVR_InitManager.Instance.LeftHandInput.OnTouchPadDown += OnTouchPadDown;
}
void OnDisable() {
SteamVR_InitManager.Instance.OnLeftDeviceActive -= OnLeftDeviceActive;//左手柄激活
SteamVR_InitManager.Instance.OnRightDeviceActive -= OnRightDeviceActive;//右手柄激活
}
}
下一章我主要介绍手柄和射线事件的相结合代码,以及抛物线的绘制和移动,欢迎大家关注
标签:
原文地址:http://www.cnblogs.com/jqg-aliang/p/5731237.html