作者: ericzwhuang
前言
目前Google官方推出的VR設備有DayDream(2016年推出)和Cardboard(2014年推出)兩種。
- Daydream是消費級VR解決方案,提供了手持遙控設備Controller,提高渲染效率,優化延遲。
- Cardboard是體驗級VR解決方案,屬於入門級VR設備的首選,物美價廉。
本文針對的VR設備是Cardboard,Google為Cardboard提供的VR SDK主要有四種,分別是Android,iOS,Unity和Unreal。本文主要闡述的是如何在Unity環境下開發VR場景,實現視線與物體的簡單交互。
軟件准備
工欲善其事,必先利其器,首先介紹開發過程中需要用到的軟件環境和開發工具
- Unity Editor 編輯圖形界面的利器,所見即所得,使用的是Unity 5.4.2f2個人版
- Visual Studio 微軟出品的C#開發編輯器,使用的是Visual Studio 2015個人版
- VR SDK 使用的是Google VR為Unity提供的SDK ,下載得到GoogleVRForUnity.unitypackage文件
- Android SDK Android開發必備環境,推薦和Android Studio配套下載
- JDK JAVA開發必備環境,需要配置環境變量
- Cardboard 最便宜的VR體驗設備盒子,可以網購或自行組裝
開發流程
本文將通過以下步驟來完成開發過程,使用清晰直觀的圖片輔助說明
- 導入資源,構建雙目視圖
- 添加交互物體
- 代碼編寫
- 建立物體、代碼、事件之間關聯關系
- Android平台打包
導入資源,構建雙目視圖
新建項目之后,從Assets -> Import Package中引入之前下載完成的 unitypackage 包,Project中的Assets文件夾下會添加兩個文件夾GoogleVR 和 Plugins,包含Google為VR提供的一系列模板文件。
目前在Cardboard上展示的視圖一般都是雙目視圖,又稱分屏視圖,左右眼看見的圖片內容略有不同,圖像相互疊加形成立體效果。將Assets->GoogleVR->Prefabs->GvrViewerMain.prefab移到結構列表中,選中GvrViewerMain ,在Inpsector中設置Screen Size值為Nexus 5 ,Viewer Type值為Cardboard May 2015。
此時在Scene視圖中看不出有什么變化,點擊運行之后可以看出已經有雙目效果
Windows下按住Alt+移動鼠標,可以轉動視角,目前還沒有添加任何物體,VR中需要和視野范圍內的物體進行交互,這就引出了一個問題:如何確定當前看到的是哪個物體。你也許會說是當前視野的視線聚焦的位置,事實也的確如此,如何將他標記出來呢?
為了有更好的用戶體驗,Google早就為我們提供了良好的呈現方式,稱之為Gaze(注視、凝視)。
將Assets->GoogleVR->Prefabs->UI->GvrReticlePointer.prefab 移到Main Camera結構下。注意這里Main Camera 和GvrReticlePointer是上下層級關系,不是並列關系。
添加交互物體
選中Main Camera,在Inspector中的底部選擇Add Component ,添加GvrPointerPhysicsRaycaster
這個組件可以讓camera與物體進行互動,Raycaster是光線發射的意思,好比攝像頭發出的光,如果照射到物體,物體就會做出反應。添加之后如圖所示
此時運行項目,就可以看見左右屏幕中間(不是正中間)都會有個白色的點,也就是上面提到的注視的點。移動方向和位置,項目會以第一人稱的視角去觀察。
項目只需要實現一個最簡單的例子:視線聚焦到物體的時候物體變色,視線移開時物體恢復原狀。首先我們創建一個球體Sphere,在Hierarchy的空白處鼠標右鍵點擊->3D Object->Sphere,視圖中會出現一個球體,位置默認是原點坐標(0,0,0),需要將Sphere移到camera的可見范圍內,在Scene模式下可以點擊camera查看攝像頭的視角和范圍,也可以在Game模式觀察是否可以看到物體,Game模式下的所見內容就是camera的視野內容。點擊Sphere可以看見Inspector中的相關屬性,主要有位置、旋轉角度和規模等。
代碼編寫
接下來需要編寫代碼來實現交互效果了,在Unity中一般使用C#或JavaScript來編寫,Unity默認是使用MonoDevelop編輯器,但是一般編寫C#是用Visual Studio編輯器,這里我采用的就是Visual Studio來編寫C#。
在Assets下創建Script文件夾,主要存放代碼文件。
在Script文件夾中鼠標右擊創建代碼文件,Create->C# Script,命名為GazeToSphere,主要的代碼如下所示:
using UnityEngine; using System.Collections; public class GazeToSphere : MonoBehaviour { // Use this for initialization void Start () { ChangeColor(false); } // Update is called once per frame void Update () { } public void GazeEnter() { ChangeColor(true); } public void GazeExit() { ChangeColor(false); } public void ChangeColor(bool gaze) { GetComponent<Renderer>().material.color = gazedAt ? Color.black : Color.white; } }
MonoBehaviour是每個腳本的基類,Javascript腳本自動繼承MonoBehaviour ,使用C#時,需要顯式繼承MonoBehaviour,其中Start() ,Update()等方法是可以重寫的。
下面對各個方法進行解釋:
- Start() 物體初始化方法,可重寫。
- Update() 物體刷新的方法,可重寫。頻率是每幀刷新,幀數可以由fps參數得知,如果fps是60,則表示每秒刷新60次,兩次update之間的時間間隔是1/60s。
- GazeEnter() 自定義的方法,表示視線進入物體。
- GazeExit() 自定義的方法,表示視線離開物體。
- isGazed() 自定義的方法,表示對當前渲染的物體進行變色處理。
Visual Studio默認不會自動保存文件,所以編寫完代碼之后記住要手動保存文件,否則在后面關聯過程會出現問題。目前實現的功能是視線進入球體,球體變成黑色,視線離開物體,球體變成白色。
建立物體、代碼、事件之間關聯關系
下一步是將物體、代碼、事件之間關聯起來,選中Sphere,在Inspector中點擊Add Component ,搜索創建的C#文件的名字GazeToSphere,添加相關部件。
首先建立視線與物體之間的關聯關系,需要添加事件系統,在Hierarchy的空白處鼠標右鍵點擊->UI->Event System ,選中Event System 之后,在Inspector中點擊Add Component 按鈕,然后在輸入框中搜索GvrPointertInputModule ,添加對應模塊。
接下來就要將之前寫的GazeToSphere 和這個module關聯在一起,再回到Sphere 上,繼續添加component,搜索Event Trigger並添加。
然后要添加觸發的事件類型,點擊Add New Event Type ,選擇添加Pointer Enter ,表示進入事件,然后點擊+ 按鈕,
在None(Object) 中點擊右側的小圓圈,
會彈出框中選擇當前的Sphere 對象,
然后點擊No Function 這一欄,在下拉框中選擇GazeToSphere->GazeEnter ,這里需要注意之前提到的要主動保存文件,否則在這里無法索引到GazeToSphere的GazeEnter方法。
上面的操作主要實現的內容就是當視線進入球體時,會觸發GazeEnter方法,而GazeEnter 方法執行的就是將球體的顏色變成黑色。因此還需要添加離開事件,按照同樣的方法,再添加一個Event Type ,這次選擇添加Pointer Exit ,表示離開事件,關聯的是GazeToSphere的GazeExit 方法,結果如圖所示。
在pc上測試的效果如圖所示,焦點在球體外的時候,球體顯示白色。
當焦點進入球體時,焦點會從白點變成一個圓圈,表示Gaze狀態變化,球體變成黑色。
Android平台打包
將項目保存成.scene 類型文件,然后點擊File->Build Settings ,選擇Android平台,首次移植到Android時會顯示如下圖片。
點擊Open Download Page ,會自動下載一個UnitySetup-Android-Support-for-Editor 文件,點擊安裝,會提示先關閉Unity編輯器,安裝完成之后再次打開Unity編輯器。目前還只是在PC端上測試,下面需要打包成可以在Android系統上運行的apk文件。這里需要配置SDK和JDK的路徑,點擊Edit->Preferences->External Tools ,勾選默認使用VS打開C#文件,配置SDK和JDK路徑,NDK路徑可以先暫時不用配置。
點擊File->Build Settings ,點擊Add Open Scenes ,選中保存的項目,在平台中選擇Android,點擊底部的Player Settings
在這些位置需要編輯包名,主要是公司名稱和產品名稱,注意不能有數字。
在Resolution and Presentation 中勾選Landscape Left 或者Landscape Right,因為Cardboard 中默認手機是橫向放置,所以默認選擇橫屏,一般習慣是Left。
然后點擊Build And Run ,選擇安裝包的位置,等待手機運行即可(當然手機要通過usb連着電腦了,而且只能連一台手機,因為沒有可以選擇安裝在哪一台手機上的過程),第一次編譯過程會比較慢,之前一直是在Windows平台編譯,這次轉換平台,很多資源需要重新轉換。接下來就把手機放在Cardboard中,感受一下VR的效果吧。