从零开始丨使用Unity3D进行VIVE VR游戏开发(附项目源码)

发表于2016-06-21
评论0 8.8k浏览

SteamVR插件的导入

使用Unity3D进行VR游戏的开发,首先需要具备以下条件

1.       拥有一台显卡不低于GTX960性能的主机

2.       拥有一部VR设备,HTC Vive或者Oculus,因为只有连接上VR设备,Unity才能进行正常的调试(本文使用的是Vive设备)

3.       下载Valve的游戏平台Steam 

4.       下载Unity3D插件商店中SteamVR插件

这几项缺一不可,没有VR设备的开发者,虽然能进行VR项目的开发,但是不能调试不能体验VR的效果,实际上是非常蛋疼的一件事。

另外吐槽一点,VR的调试需要带上VR设备,这个时候如果要动态的在项目中进行各种调试会非常的不方便。。。笔者尝试在VR设备中调出桌面进行操作也由于摇杆的操作比鼠标操作差很多而倍感不爽。。。所以没有VR设备的小伙伴们,赶快入手一个VR设备是正经,当然你也可以先通过学习如何开发来做一个前期的预热。

首先第一步,我们要做的是打开Steam,点击右上角的VR小标记来启动VR设备,第一次启动需要设置一下VR设备的房间环境,这点我就不多说了,不同的VR设备有不同的设置方式。最终能够识别出你的VR设备即可。本教程以HTC出的VIVE设备进行讲解。

SteamVR插件是全免费的,是Valve公司免费提供给大家的,这一点真是良心啊,如果有遇到无法下载或者下载非常慢的情况,本文最后将会提供插件的下载,有需要的同学请自行下载

截止本稿完成日期,最新版本为1.1.0,这个插件不大,只有几M,很实惠的插件哟。

好了,说了那么多,我们开始实战吧,首先创建一个新的Unity3D项目,然后导入我们的SteamVR插件。

在项目的根目录或者任意空白的地方点击右键,选择Import Package→Custom Package导入下载好的unity插件包(如果是从官网插件商店下载的,则会自动弹出导入窗口,不用这一步了)

导入所有的文件(如果是用旧版本更新,则更新所有的文件即可),点击Import

导入完成之后会弹出一个Unity项目设置的窗口,选择AcceptAll接受所有即可


 

你做了一个正确的选择~被表扬了~呜哈哈~~

导入完插件之后,可以在Scenes文件夹下找到一个演示的场景,example,建议有密集恐惧症的同学慎入。。。另外在Extras下也有两个小演示,一个是抛东西,一个是握东西,都是演示摇杆的使用方式这个我们后面再讲。

带上你的VR设备,运行这些场景就开始你的VR体验之旅了。

使用SteamVR插件预制开始VR的旅程

下面这一节将会教各位同学打造自己的VR场景,这一节是非常非常简单的,简单到我用一句话就能讲完,不信?我们来试试。

新建一个场景或者打开一个已有的场景,将SteamVR/Prefabs/[CameraRig]预制拖入场景。

然后。。。然后就完了,你可以运行这个场景,你的两个手柄都识别出来了,和你刚才看到官方的演示场景一样。

细心的同鞋一定发现了控制台一直在输出什么东西,不要担心,这是因为有场景中有两个AudioListener,我们把原来场景中主摄像机上的AudioListener移除掉即可

呵呵,这一步简单吧,然后我们开始进行下一步。

如何识别手势控制以及摇杆的各种操作

这一节将教会大家如何使用脚本来识别和控制VR设备

我们首先看一下刚刚拖到场景里的CameraRig预制

最外层的CameraRig这个预制就是你的VR设备在场景中的原点位置,挪动这个对象可以挪动整个VR在场景的位置,你的视角也会随之而移动。

Controller(left)Controller(right)这个不用我多说了,这个是你的左右摇杆。有好学的同学要问了,摇杆上貌似没有区分左右的标记吧,怎么能区分哪个对象对应的是哪个摇杆呢?SteamVR默认会将第一个识别出来的摇杆作为right右摇杆,所以分左右主要看先后。最后的head不用说,就是各位同学的脑袋了,里面有两个对象,一个是作为渲染器的眼睛,一个是用来听声音的耳朵。

认识了这些东西之后,我们就开始编写一个小脚本,来识别一下他们。

Main Camera上添加一个新的cs脚本,取名为StartVR

双击打开这个脚本

写入如下代码

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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
using UnityEngine;
 
using System.Collections;
 
using Valve.VR;
 
  
 
public class StartVR : MonoBehaviour {
 
  
 
    public SteamVR_TrackedObject leftHand;
 
    public SteamVR_TrackedObject rightHand;
 
  
 
    private VRControllerState_t leftControllerState;
 
    private VRControllerState_t rightControllerState;
 
  
 
    // Use this for initialization
 
    void Start () {
 
    
 
    }
 
    
 
    // Update is called once per frame
 
    void Update() {
 
        CVRSystem system = OpenVR.System;
 
        // 左手
 
        if (system != null && system.GetControllerState((uint)leftHand.index, ref leftControllerState)) {
 
            SteamVR_Controller.Device device = SteamVR_Controller.Input((int)(uint)leftHand.index);
 
  
 
            float px = leftControllerState.rAxis0.x;
 
            float py = leftControllerState.rAxis0.y;
 
            
 
            if (device.GetPressDown(EVRButtonId.k_EButton_SteamVR_Trigger)) {
 
                Debug.Log("按下trigger键");
 
            } else if (device.GetPress(EVRButtonId.k_EButton_SteamVR_Trigger)) {
 
                Debug.Log("按住trigger键");
 
            } else if (device.GetPressUp(EVRButtonId.k_EButton_SteamVR_Trigger)) {
 
                Debug.Log("抬起trigger键");
 
            }
 
  
 
            if (device.GetPressDown(EVRButtonId.k_EButton_ApplicationMenu)) {
 
                Debug.Log("按下menu键");
 
            } else if (device.GetPress(EVRButtonId.k_EButton_ApplicationMenu)) {
 
                Debug.Log("按住menu键");
 
            } else if (device.GetPressUp(EVRButtonId.k_EButton_ApplicationMenu)) {
 
                Debug.Log("抬起menu键");
 
            }
 
  
 
            if (device.GetTouchDown(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("触摸pad面板");
 
            } else if (device.GetTouch(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("持续触摸pad面板");
 
            } else if (device.GetTouchUp(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("从pad面板上抬起手");
 
            }
 
  
 
            if (device.GetPressDown(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("按下pad按钮");
 
            } else if (device.GetPress(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("按住pad按钮");
 
            } else if (device.GetPressUp(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("抬起pad按钮");
 
            }
 
  
 
  
 
            if (device.GetPressDown(EVRButtonId.k_EButton_Grip)) {
 
                Debug.Log("按下Grip键");
 
            } else if (device.GetPress(EVRButtonId.k_EButton_Grip)) {
 
                Debug.Log("按住Grip键");
 
            } else if (device.GetPressUp(EVRButtonId.k_EButton_Grip)) {
 
                Debug.Log("抬起Grip键");
 
            }
 
  
 
            if (device.GetHairTriggerDown()) {
 
                Debug.Log("轻按trigger");
 
            } else if (device.GetHairTrigger()) {
 
                Debug.Log("持续轻按trigger键");
 
            } else if (device.GetHairTriggerUp()) {
 
                Debug.Log("抬起轻按trigger键");
 
            }
 
        }
 
  
 
        // 右手
 
        if (system != null && system.GetControllerState((uint)rightHand.index, ref rightControllerState)) {
 
            SteamVR_Controller.Device device = SteamVR_Controller.Input((int)(uint)rightHand.index);
 
  
 
            float px = rightControllerState.rAxis0.x;
 
            float py = rightControllerState.rAxis0.y;
 
  
 
            if (device.GetPressDown(EVRButtonId.k_EButton_SteamVR_Trigger)) {
 
                Debug.Log("按下trigger键");
 
            } else if (device.GetPress(EVRButtonId.k_EButton_SteamVR_Trigger)) {
 
                Debug.Log("按住trigger键");
 
            } else if (device.GetPressUp(EVRButtonId.k_EButton_SteamVR_Trigger)) {
 
                Debug.Log("抬起trigger键");
 
            }
 
  
 
            if (device.GetPressDown(EVRButtonId.k_EButton_ApplicationMenu)) {
 
                Debug.Log("按下menu键");
 
            } else if (device.GetPress(EVRButtonId.k_EButton_ApplicationMenu)) {
 
                Debug.Log("按住menu键");
 
            } else if (device.GetPressUp(EVRButtonId.k_EButton_ApplicationMenu)) {
 
                Debug.Log("抬起menu键");
 
            }
 
  
 
            if (device.GetTouchDown(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("触摸pad面板");
 
            } else if (device.GetTouch(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("持续触摸pad面板");
 
            } else if (device.GetTouchUp(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("从pad面板上抬起手");
 
            }
 
  
 
            if (device.GetPressDown(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("按下pad按钮");
 
            } else if (device.GetPress(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("按住pad按钮");
 
            } else if (device.GetPressUp(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                Debug.Log("抬起pad按钮");
 
            }
 
  
 
  
 
            if (device.GetPressDown(EVRButtonId.k_EButton_Grip)) {
 
                Debug.Log("按下Grip键");
 
            } else if (device.GetPress(EVRButtonId.k_EButton_Grip)) {
 
                Debug.Log("按住Grip键");
 
            } else if (device.GetPressUp(EVRButtonId.k_EButton_Grip)) {
 
                Debug.Log("抬起Grip键");
 
            }
 
  
 
            if (device.GetHairTriggerDown()) {
 
                Debug.Log("轻按trigger");
 
            } else if (device.GetHairTrigger()) {
 
                Debug.Log("持续轻按trigger键");
 
            } else if (device.GetHairTriggerUp()) {
 
                Debug.Log("抬起轻按trigger键");
 
            }
 
        }
 
    }
 
}


在场景中将VR的左右手对象拖到脚本相应参数的位置

然后不要带眼镜,直接运行程序,点击摇杆上的各个按键,控制台就能够输出各种打印信息了。

1.       menu

2.       pad面板

3.       系统键

4.       指示灯

5.       充电口

6.       定位装置

7.       trigger

8.       grip

9.       

使用脚本代码漫游3D场景

熟悉了以上流程,基本我们就可以开始制作VR游戏了,下面这一节将会教大家如何使用摇杆来控制视角在VR场景中漫游移动

首先修改代码如下:

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
using UnityEngine;
 
using System.Collections;
 
using Valve.VR;
 
  
 
public class StartVR : MonoBehaviour {
 
  
 
    public SteamVR_ControllerManager root;
 
  
 
    public SteamVR_GameView head;
 
  
 
    public SteamVR_TrackedObject leftHand;
 
    public SteamVR_TrackedObject rightHand;
 
  
 
    private VRControllerState_t leftControllerState;
 
    private VRControllerState_t rightControllerState;
 
  
 
    // Use this for initialization
 
    void Start () {
 
    
 
    }
 
    
 
    // Update is called once per frame
 
    void Update() {
 
        CVRSystem system = OpenVR.System;
 
        // 左手
 
        if (system != null && system.GetControllerState((uint)leftHand.index, ref leftControllerState)) {
 
            SteamVR_Controller.Device device = SteamVR_Controller.Input((int)(uint)leftHand.index);
 
  
 
            float px = leftControllerState.rAxis0.x;
 
            float py = leftControllerState.rAxis0.y;
 
  
 
            if (device.GetPress(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                OnPadButtonPressDown(px, py);
 
            }
 
        }
 
  
 
        // 右手
 
        if (system != null && system.GetControllerState((uint)rightHand.index, ref rightControllerState)) {
 
            SteamVR_Controller.Device device = SteamVR_Controller.Input((int)(uint)rightHand.index);
 
  
 
            float px = rightControllerState.rAxis0.x;
 
            float py = rightControllerState.rAxis0.y;
 
  
 
            if (device.GetPress(EVRButtonId.k_EButton_SteamVR_Touchpad)) {
 
                OnPadButtonPressDown(px, py);
 
            }
 
        }
 
    }
 
  
 
    public void OnPadButtonPressDown(float px, float py) {
 
        float area = 0.8f;
 
        float speed = 1f;
 
        if (px > 0f && py > -area && py < area) {
 
            // right
 
            root.gameObject.transform.position += head.gameObject.transform.right * speed;
 
        }
 
        if (px < 0f && py > -area && py < area) {
 
            // left
 
            root.gameObject.transform.position -= head.gameObject.transform.right * speed;
 
        }
 
        if (py > 0f && px > -area && px < area) {
 
            // up
 
            root.gameObject.transform.position += head.gameObject.transform.forward * speed;
 
        }
 
        if (py < 0f && px > -area && px < area) {
 
            // down
 
            root.gameObject.transform.position -= head.gameObject.transform.forward * speed;
 
        }
 
    }
 
}


 

 

然后将场景中VR设备的对象拖入相应位置

为了区分场景的位置,可以在空的场景中添加一些3D模型,或者你也可以打开以前做好的各种场景

接下来,戴上眼镜,运行程序,按下双手任意pad上的上下左右方向,就可以根据当前视角的前后左右进行移动了。这样我们的第一个VR程序就完成了,恭喜大家买入了VR开发的第一道门槛~

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引