写给VR手游开发小白的教程:(二)UnityVR插件CardboardSDKForUnity解析(一)

现在我们已经有了开发环境,还没安装环境的小伙伴可以看上一篇:

(一)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。(这个变量是控制扭曲的,开或者关的效果如下,差距应该一目了然)

写给VR手游开发小白的教程:(二)UnityVR插件CardboardSDKForUnity解析(一)_第1张图片

写给VR手游开发小白的教程:(二)UnityVR插件CardboardSDKForUnity解析(一)_第2张图片

同上还有VRModeEnabled(VR模式的使能,开了就是分屏),EnableAlignmentMarker(就是下图黄圈中间那根线,关了,线就没了),EnableSettingsButton(就是下图绿圈内的设置按钮,同样也是关了就没了),AutoDriftCorrection(这个属性还没搞懂先放着),NeckModelScale(这个是专业术语,应该是颈部的微调吧...猜的,值在0-1之间,调整的话视角会有微小的变化,但可以忽略不计)

写给VR手游开发小白的教程:(二)UnityVR插件CardboardSDKForUnity解析(一)_第3张图片

后面从#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了。

你可能感兴趣的:(Android开发,插件,unity3d,sdk,手游)