zoukankan      html  css  js  c++  java
  • SteamVR Plgins的使用(一)

    本章节主要讲解使用SteamVR Plugins插件为基础,来介绍Vive开发的入门,重点讲解设备的激活和控制接口。SteamVR Pluginsunity官方资源商店可以免费下载,这里我就不给出链接了。

    导入SteamVR Plugins后,不要在他的示例上去做开发,那样你会走弯路。因为这个插件的设备初始化代码很怪异,甚至可以说无法使用。因此我们需要自己写设备的初始化代码以及设备的操作接口。

    我们对原插件进行封装后就可以愉快的使用了,之后怎么开发就和这个设备无关了,我们开发这类的应用无非是获取相关的接口操作。

    新建场景,然后在Camera上添加组件SteamVR_Camera,然后点击 Expand 按钮,之后我们就得到了一个基本的VR相机。

    然后我们在Camera的下面新建两个GameObject,并命名为LeftHandRightHand。同时添加组件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;//右手柄激活
        }
    }
    

     

      下一章我主要介绍手柄和射线事件的相结合代码,以及抛物线的绘制和移动,欢迎大家关注

     

     

  • 相关阅读:
    ASP.NET MVC中获取URL地址参数的两种写法
    SQL Server之存储过程基础知识
    ASP.NET MVC 四种Controller向View传值方法
    Js数据类型、Json格式、Json对象、Json字符串
    调用微信内置的方法及wx.config的配置问题
    ref和out的使用及区别
    ASP.NET MVC post请求接收参数的三种方式
    Asp.Net Mvc 路由机制
    Asp.Net MVC中Action跳转小结
    JS应用MD5散列计算头像URL
  • 原文地址:https://www.cnblogs.com/jqg-aliang/p/5731237.html
Copyright © 2011-2022 走看看