Skip to main content
 首页 » 资源教程

SteamVR Plgins的使用(一)

2016年08月24日 16:01:406290

本章节主要讲解使用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,来获取手柄的激活和相关的初始化代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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,我基本上把所有的手柄控制事件都写完了.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
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,接下来写一个简单的测试类来测试相关的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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;//右手柄激活
    }
}

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

更多AR新闻就在中国AR网(http://www.chinaar.com/)


评论列表暂无评论
发表评论