现在我们已经有了开发环境,还没安装环境的小伙伴可以看上一篇:
(一)Unity3D进行Android开发的环境搭建(虚拟机调试)
今天主要介绍的是谷歌为自己的Cardboard平台提供的开发工具Cardboard SDK插件解析。Cardboard是谷歌公司在14年发布的一款极具创意的产品,由手机内部的传感器支持,它仅需硬纸板和两片透镜就能打造移动平台上的VR体验。Cardboard这里不多做介绍,网上可以买到原装正版,价格在50以内很便宜,有条件的人可以去体验一下。
在正式开始之前,先说明一下本节需要对Unity3D引擎有一些基础才能较流畅的看完,若是中间有疑问可以评论也可私信,疑问较多也可以再补充一章专门介绍基础的东西。
上一章忘记说了,如果是VR应用的话,就不要在虚拟机里跑了(虚拟机根本没有传感器去定位你的头部,也就不存在VR一说了,不过简单的小游戏还是可以在虚拟机上跑的,所以如果是跑大型应用的话,还是选择真机吧),虚拟机的存在其实纯粹是为了学习示例用的。
没有真机的同学,这个demo在Unity里也可以跑,具体按住Alt移动鼠标就相当于转动头部,按住Ctrl移动鼠标相当于歪脖子看。
/***************************************************************分割线*******************************************************************/
首先要为Unity安装这个插件,对于本插件,目前网上有些资源是不带demo的,正好我这边有一个带demo的,附上下载地址:
http://download.csdn.net/detail/mao_xiao_feng/9577849
导入以后,工程目录下多了以下两个文件夹,双击打开DemoScene下的场景
场景大概就是以下这个样子了,这个demo是插件中提供的官方示例,一定要把里面所有东西都研究透,才能很好理解SDK当中的每一个脚本的功能。
直接切入主题,看到CardboardMain这个物体已经被设为了Prefab,那么它一定是获得VR效果的关键性物体,事实上所有VR的实现都在这个物体极其子物体下,我们把它一层层的剥离开来。
CardboardMain物体上只绑定了这一个脚本,开始看源码
The Cardboard object communicates with the head-mounted display in order to:Query the device for viewing parameters Retrieve the latest head tracking data Provide the rendered scene to the device for distortion correction 翻译/*Cardboard物体与头盔显示器进行交互以获得设备上的一些参数,返回最近头部跟踪数据,为被渲染的场景提供失真校正*/
定义了一个Cardboard类型的静态公有变量SDK,主要用来获取游戏中的Cardboard.cs脚本,可以看到它是只读的,即SDK提供了一个共有的访问接口,在任何时候它都只有一个实例。 // The singleton instance of the Cardboard class. 翻译/*Cardboard类的单件实例*/---关于单件模式,编程用的还是挺多的。
BaseVRDevice类型的私有静态变量device,BaseVRDevice也是插件当中定义的一个类,注意!!它与Cardboard类不同,它不是脚本类!!这个变量用的比较多 // The VR device that will be providing input data. 翻译/*VR设备(在这里直接理解为手机吧!)提供输入的数据*/
公有bool类型的变量DistortionCorrection,默认为true。DistortionCorrection我把它翻译为失真校正(暂且这样翻译吧),读属性不说了,写属性加了个if语句,想说明假如设备接入了并且支持失真校正功能,才能修改它的值,不然一直为true。(这个变量是控制扭曲的,开或者关的效果如下,差距应该一目了然)
同上还有VRModeEnabled(VR模式的使能,开了就是分屏),EnableAlignmentMarker(就是下图黄圈中间那根线,关了,线就没了),EnableSettingsButton(就是下图绿圈内的设置按钮,同样也是关了就没了),AutoDriftCorrection(这个属性还没搞懂先放着),NeckModelScale(这个是专业术语,应该是颈部的微调吧...猜的,值在0-1之间,调整的话视角会有微小的变化,但可以忽略不计)
后面从#if UNITY_IOS到#endif中间的部分是预编译部分,根据ios,unity_editor,android选择性的编译,可以根据自己的平台选择性的看。我们现在使用unity编辑器在运行,所以他编译的是#if UNITY_EDITOR到#endif中间的这部分。
RenderTexture类型的公有变量StereoScreen,渲染纹理是一种即时更新的纹理。//The texture that Unity renders the scene to. This is sent to the VR device,which renders it to screen, correcting for lens distortion. 翻译/*Unity渲染场景产生的纹理,它被传输到VR设备上,在屏幕上被绘制产生正确的透镜弯曲效果*/这个变量的读属性当vr模式或者distortionCorrection关闭时,为null,写属性也只有在支持distortionCorrection的时候可以使用,总的来说,可以把它看作产生弯曲效果的一个工具或者一个中间量。
bool类型只读属性的UseDistortionEffect,这个量是用来判断透镜效果是否开启的量,后面会用到。
CardboardProfile类型的公有变量Profile,也是只读的。 // Describes the current device, including phone screen. 翻译/*描述当前设备,包括手机屏幕*/
公有枚举类型Eye。 // Distinguish the stereo eyes. 翻译/*看立体效果时用来区分左右眼*/
公有枚举类型Distortion。这个量主要控制在某些特殊情况下是否需要透镜预览,在下面会用到
Pose3D类型的公有量HeadPose。 // The transformation of head from origin in the tracking system. 翻译/*在跟踪在系统中,头部距离起始点的信息*/由于这里Pose3D也是插件自定义的类,后续需要分析Pose3D这个类才能知道信息是如何传递的。同理还有变量EyePose。
返回Matrix4x4类型的方法Projection(Eye eye, Distortion distortion = Distortion.Distorted)返回结果是device.GetProjection(eye, distortion);从两个参数推断这个方法是要根据眼睛计算返回一个投影矩阵,在Unity圣典中阐述过Matrix4x4类型的投影矩阵,关于投影矩阵,涉及到计算机图形学的东西,我目前也正在学习,给一个链接大家可以学习一下。
http://blog.csdn.net/yanwei2016/article/details/7326180
Viewport(Eye eye, Distortion distortion = Distortion.Distorted)方法返回视口矩形,应该是处理在屏幕上的位置的一个方法
Vector2类型的变量ComfortableViewingRange,只读,控制我们去看空间中物体的一个最舒服的距离范围,这个量不需要去配置,理解就行。
私有方法InitDevice()用于初始化设备,因为涉及到BaseVRDevice类,我们以后再去解析其细节。
私有方法AddDummyCamera()用来添加一个黑色背景,当然背景也可以自己更换。
一些琐碎的定义先到这里
/********************************************************分割线********************************************************************/
NOTE: Each scene load causes an OnDestroy of the current SDK, followed by and Awake of a new one. That should not cause the underlying native code to hiccup. Exception: developer may call Application.DontDestroyOnLoad on the SDK if they want it to survive across scene loads.
翻译/*说明:每一个新场景被加载会导致现在sdk的destroy,然后产生新的sdk,这会发生一些问题(这句话实在不会翻译了),所以开发者们在切换场景的时候如果希望sdk依然存活,可以使用Application.DontDestroyOnLoad*/。这里其实可以间接的说明SDK是采用的单件模式,因为我们无法用new()去创建,而且自始而终最多只有一个实例。
比较关键的awake函数来了
void Awake() {
if (sdk == null) {
sdk = this;
}
if (sdk != this) {
Debug.LogWarning("Cardboard SDK object should be a singleton.");
enabled = false;
return;
}
#if UNITY_IOS
Application.targetFrameRate = 60;
#endif
InitDevice();
AddDummyCamera();
StereoScreen = null;
}相信上面的语句根据我之前的解释大家都能看懂了
这个类中没有Update()所以我认为更新可能放在BaseVRDevice类型的device里面了。
我先码到这里(太累了),后面接着此篇,另外会解析BaseVRDevice这个类(很重要!!),还有CardboardProfile这个类。
总结:这一章还只是把每个类的功能和大致框架整理了一下,并没有涉及到很多细节的东西,也没有涉及到原理,注意我们现在还在顶端的父物体Cardboard物体上分析,后面当涉及到原理的的时候,就要开始看下层的Head,和它的子物体几个camera了。