如何用Unity和cardboard vr做一款VR游戏

4057人阅读
Unity3D移动端(7)
上一章讲了Cardboard这个类,做一个总结,这个类总就是给一些私有的变量去提供了共有的接口,以供用户去修改他们的值。这些量大多都是用户级别的变量,多是控制一些功能的使能,例如是否开启VR模式等。还有一个重要作用,类实现了自身的单例化,如下:
public class Singleton
& & private static Singleton _instance =
& & //将构造函数设为private,防止客户代码通过new实例化对象
& & private Singleton()
& & public static Singleton CreateInstance()
& & & & & & if(_instance == null)
& & & & & & _instance = new Singleton();
& & & & return _
这就是单件模式一个重要的例子,用户永远只能通过自定义的公有方法去实例化或者返回已经实例化的对象。
单件模式,有两个好处:
第一个是资源共享,例如在这个demo中,我们只希望VR Mode Enabled这个变量只有一个,外部共享的调用它。如果它有两个,这样就会导致难以处理一些请求和资源的损耗。
第二个是信息交互会更加简便,就像为什么Unity里面永远只有一个Main Camera,而我们去find它的时候不需要遍历的去搜索判断它的名字,道理是一样的。
我们还简单介绍了以下几项属性的功能(其中Editor Mock Settings是Unity编辑器下运行的设置,一般不会做改动的,也对手机上运行没什么影响)
/************************************************************分割线****************************************************************/
好了,接下来进入这次的主题,先上图
这是VRDevice文件夹下所有类的继承关系,可以看到所有类都继承于同一个基类,BaseVRDevice
BaseVRDevice的介绍
// Represents a vr device that this plugin interacts with. 代表了与这个插件交互的VR设备
这个类里面应该定义了作为VR设备必须要实现的一些方法,但我们不必关注是怎样实现的,这些方法会在子类里面根据不同的平台(ios,android)重写,给出详细的实现步骤。
我们把重要的和不重要的归个类
public virtual RenderTexture CreateStereoScreen()
//Creating new default cardboard screen texture.为Cardboard屏幕生成一个新的默认RenderTexture,RenderTexture是一个实时更新的纹理,动态的,上节说过
public Pose3D GetHeadPose()
protected MutablePose3D headPose = new MutablePose3D();
//两个一起讲,headPose是变量,记录了头部的位置信息,注意是protected的,GetHeadPose()得到头部的位置,返回的是headPose,这个方法是public的
public Pose3D GetEyePose(Cardboard.Eye eye)
protected MutablePose3D leftEyePose = new MutablePose3D();
protected MutablePose3D rightEyePose = new MutablePose3D();
//同理,眼睛位置
public Matrix4x4 GetProjection(Cardboard.Eye eye,Cardboard.Distortion distortion = Cardboard.Distortion.Distorted)
protected Matrix4x4 leftEyeDistortedP
protected Matrix4x4 rightEyeDistortedP
protected Matrix4x4 leftEyeUndistortedP
protected Matrix4x4 rightEyeUndistortedP
//根据眼睛类型(左右眼)和是否应用透镜弯曲效果来返回一个Projection(投影),这个投影是Matrix4x4类型的,Unity官方对投影矩阵的解释是&如果你改变这个矩阵,相机的渲染不再基于它的fieldOfView更新,直到调用ResetProjectionMatrix.只有当真正需要一个非标准的投影时,才使用自定义投影。
public Rect GetViewport(Cardboard.Eye eye,Cardboard.Distortion distortion = Cardboard.Distortion.Distorted)
protected Rect leftEyeDistortedV
protected Rect rightEyeDistortedV
protected Rect leftEyeUndistortedV
protected Rect rightEyeUndistortedV
//根据眼睛类型(左右眼)和是否应用透镜弯曲效果来返回一个Viewport(视口),这个视口是Rect 类型的,Rect类型很简单,里面存着(x,y,w,h)四个量,而每个量分别代表的是如下图,而一个camera呈现的画面,它在屏幕上占多大的地,就是以视口决定的。
public abstract void UpdateState();
public abstract void UpdateScreenData();
public abstract void Recenter();
public abstract void PostRender(bool vrMode);
//又来四个抽象方法,从字面意思上看,是状态更新,屏幕数据更新,重新定位中心,完成渲染后
public virtual void OnPause(bool pause)
//当停止了,就不再UpdateScreenData()
public virtual void OnFocus(bool focus)
public virtual void Reset()
public virtual void OnApplicationQuit()
public virtual void Destroy()
//由字面意思就可以理解
protected void ComputeEyesFromProfile()
//这个函数很关键!!!官方打的注释是// Compute left eye matrices from screen and device params,意思就是根据设备的参数计算左眼的观测信息
/****************************************************分割线************************************************************/
这一部分对ComputeEyesFromProfile()函数做一个详细介绍
首先这个方法中用到的数据都是来源于CardboardProfile这个类,这个类中记录了Cardboard设备的各项参数
第一句话建立了Matrix4x4 leftEyeView这个量,然后把一个4*4的单位矩阵赋给他
第二句话涉及到了CardboardProfile里的Lenses,想要解释清楚这部分,需要画三张图
Lenses里面一些量标注如上图。
还有MaxFOV这个量
public struct MaxFOV {
& & &// Towards the side of the screen.
& & &// Towards the center line of the screen.
& & &// Towards the top of the screen.
& & &// Towards the bottom of the screen.
这个量表示我们视野的最大值,是用角度来定义的,如outer这个量就是俯视图中,∠ABC的大小,inner就是∠CBD的大小了
接着第二句话leftEyeView[0, 3] = -Profile.device.lenses.separation / 2,这就是一个赋值语句,给第4列的第一个元素赋了值
第三句话leftEyePose.Set(leftEyeView),从这句话可以看出了leftEyeView这个矩阵里面是存储了眼睛的位置信息的,后续看了Set()函数,矩阵的第四列存了Position,第二第三列存了Orientation朝向信息。
再看后面&float[] rect = new float[4];
Profile.GetLeftEyeVisibleTanAngles(ref rect);这两句话,新建了一个数组,在一个方法GetLeftEyeVisibleTanAngles中修改了数组里的元素的值
public void GetLeftEyeVisibleTanAngles(ref float[] result) {
// Tan-angles from the max FOV.
float fovLeft = (float) Math.Tan(-device.maxFOV.outer * Math.PI / 180);
float fovTop = (float) Math.Tan(device.maxFOV.upper * Math.PI / 180);
float fovRight = (float) Math.Tan(device.maxFOV.inner * Math.PI / 180);
float fovBottom = (float) Math.Tan(-device.maxFOV.lower * Math.PI / 180);
// Viewport size.
float halfWidth = screen.width / 4;
float halfHeight = screen.height / 2;
// Viewport center, measured from left lens position.
float centerX = device.lenses.separation / 2 - halfW
float centerY = -VerticalLensO
float centerZ = device.lenses.screenD
// Tan-angles of the viewport edges, as seen through the lens.
float screenLeft = device.distortion.distort((centerX - halfWidth) / centerZ);
float screenTop = device.distortion.distort((centerY + halfHeight) / centerZ);
float screenRight = device.distortion.distort((centerX + halfWidth) / centerZ);
float screenBottom = device.distortion.distort((centerY - halfWidth) / centerZ);
// Compare the two sets of tan-angles and take the value closer to zero on each side.
result[0] = Math.Max(fovLeft, screenLeft);
result[1] = Math.Min(fovTop, screenTop);
result[2] = Math.Min(fovRight, screenRight);
result[3] = Math.Max(fovBottom, screenBottom);
}看一下GetLeftEyeVisibleTanAngles这个函数,先是把FOV角度转换成了正切值,再取到了屏幕相对于左眼的正切角,相比取了一个最小值,可以这样理解,如果手机屏幕比正常视野大了,那么我们看不全整个屏幕,为了有更好的体验,需要以视野作为标准,当视野比屏幕大了,当然是以手机屏幕作为标准更好一些。
以上函数完成了以后,rect的值产生了变化,接下来就需要应用这些值,leftEyeDistortedProjection = MakeProjection(rect[0], rect[1], rect[2], rect[3], 1, 1000);计算投影矩阵,因为上一步,我们做了distort变换,可以把distort理解为经过了透镜的光线折射,所以投影矩阵的结果应该也是distort的,camera呈现的画面就会是这样
当无透镜的时候Profile.GetLeftEyeNoLensTanAngles(ref rect);
leftEyeUndistortedProjection = MakeProjection(rect[0], rect[1], rect[2], rect[3], 1, 1000);会做一个inverse distort,即distort的逆变换,得到的自然是无透镜的情况
直到这里,我们说的都是Camera的Projection,他跟viewport是有区别的,后面执行的&&
leftEyeUndistortedViewport = Profile.GetLeftEyeVisibleScreenRect(rect);
leftEyeDistortedViewport = leftEyeUndistortedV
处理的是camera的viewport,即在屏幕上划定一个矩形,camera捕捉到的画面都将在矩形中显示,这在游戏分屏技术中用的很多(比如两个玩家对抗,在一个屏幕中显示两个画面),当然viewport的划定与是否需要distort无关,这样leftEyeDistortedViewport与leftEyeUndistortedViewport 应该是一个值。
/****************************************************分割线************************************************************/
public virtual bool SupportsNativeDistortionCorrection(List&string& diagnostics)
//一个用来判断是否支持NativeDistortionCorrection的方法,需要满足两个条件,支持RenderTexture和Unity4.5版本以上,才能支持透镜扭曲的效果
public virtual bool SupportsNativeUILayer(List&string& diagnostics)
//同理,但是这个NativeUILayer仅需要Unity4.5以上版本一个条件
public abstract void SetDistortionCorrectionEnabled(bool enabled);
public abstract void SetVRModeEnabled(bool enabled);
public abstract void SetAlignmentMarkerEnabled(bool enabled);
public abstract void SetSettingsButtonEnabled(bool enabled);
public abstract void SetNeckModelScale(float scale);
public abstract void SetAutoDriftCorrectionEnabled(bool enabled);
public abstract void SetStereoScreen(RenderTexture stereoScreen);
//一堆抽象方法,后面会重写的,现在先放着吧
public abstract void UpdateState();
public abstract void UpdateScreenData();
public abstract void Recenter();
public abstract void PostRender(bool vrMode);
//又来四个抽象方法,从字面意思上看,是状态更新,屏幕数据更新,重新定位中心,完成渲染后
public virtual void OnPause(bool pause)
//当停止了,就不再UpdateScreenData()
public virtual void OnFocus(bool focus)
public virtual void Reset()
public virtual void OnApplicationQuit()
public virtual void Destroy()
//由字面意思就可以理解
OK!!BaseVRDevice就看到这里,这个类中还是有比较关键的函数的,后面会继续看子类的代码,有些地方比如怎样去计算Projection的4*4的矩阵,投影为什么要用4*4矩阵可能涉及到数学的东西了,我也不太明白,只能是看懂了以后再作介绍。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:55651次
排名:千里之外
原创:28篇
评论:39条
(1)(1)(2)(3)(8)(6)(5)(1)(3)扫一扫,访问微社区
后使用快捷导航没有帐号?
签到成功!您今天第{todayrank}个签到,签到排名竞争激烈,记得每天都来签到哦!已连续签到:{constant}天,累计签到:{days}天
当前位置: &
用unity和Google Cardboard制作VR游戏
61217/1500排名<font color="#FF昨日变化主题帖子积分
蛮牛粉丝, 积分 1217, 距离下一级还需 283 积分
蛮牛粉丝, 积分 1217, 距离下一级还需 283 积分
在线时间396 小时
爱上的顶顶顶顶顶顶顶顶顶顶大大说
每日推荐:
285/150排名<font color="#FF昨日变化11主题帖子积分
初来乍到, 积分 85, 距离下一级还需 65 积分
初来乍到, 积分 85, 距离下一级还需 65 积分
在线时间18 小时
学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习
每日推荐:
133/50主题帖子积分
注册看看, 积分 33, 距离下一级还需 17 积分
注册看看, 积分 33, 距离下一级还需 17 积分
在线时间27 小时
ddddddddddddddddddddd
每日推荐:
4400/500排名<font color="#FF昨日变化7主题帖子积分
四处流浪, 积分 400, 距离下一级还需 100 积分
四处流浪, 积分 400, 距离下一级还需 100 积分
在线时间283 小时
aaaaaaaaaaaaaaaaaaaa
每日推荐:
4400/500排名<font color="#FF昨日变化7主题帖子积分
四处流浪, 积分 400, 距离下一级还需 100 积分
四处流浪, 积分 400, 距离下一级还需 100 积分
在线时间283 小时
asfesfsetfdrs
每日推荐:
262/150主题帖子积分
初来乍到, 积分 62, 距离下一级还需 88 积分
初来乍到, 积分 62, 距离下一级还需 88 积分
在线时间48 小时
学习学习,希望能跟着做一个vr游戏
每日推荐:
5637/1000排名<font color="#FF昨日变化5主题帖子积分
熟悉之中, 积分 637, 距离下一级还需 363 积分
熟悉之中, 积分 637, 距离下一级还需 363 积分
在线时间381 小时
[]: 异界 发帖时在路边捡到 2
蛮牛币,偷偷放进了口袋.
每日推荐:
18/50主题帖子积分
注册看看, 积分 8, 距离下一级还需 42 积分
注册看看, 积分 8, 距离下一级还需 42 积分
在线时间5 小时
其实Google Cardboard开发在ios真机上抛效果真心一般
每日推荐:
266/150排名<font color="#FF昨日变化13主题帖子积分
初来乍到, 积分 66, 距离下一级还需 84 积分
初来乍到, 积分 66, 距离下一级还需 84 积分
在线时间31 小时
很好的东西
每日推荐:
266/150排名<font color="#FF昨日变化13主题帖子积分
初来乍到, 积分 66, 距离下一级还需 84 积分
初来乍到, 积分 66, 距离下一级还需 84 积分
在线时间31 小时
很好的东西
每日推荐:
266/150排名<font color="#FF昨日变化13主题帖子积分
初来乍到, 积分 66, 距离下一级还需 84 积分
初来乍到, 积分 66, 距离下一级还需 84 积分
在线时间31 小时
RE: 用unity和Google Cardboard制作VR游戏
很好的东西
[]: wx_g4H8vhUv 乐于助人,奖励 3
每日推荐:
266/150排名<font color="#FF昨日变化13主题帖子积分
初来乍到, 积分 66, 距离下一级还需 84 积分
初来乍到, 积分 66, 距离下一级还需 84 积分
在线时间31 小时
RE: 用unity和Google Cardboard制作VR游戏
很好的东西!
每日推荐:
3162/300排名<font color="#FF昨日变化15主题帖子积分
偶尔光临, 积分 162, 距离下一级还需 138 积分
偶尔光临, 积分 162, 距离下一级还需 138 积分
在线时间71 小时
很好,谢谢楼主的分享,感谢
每日推荐:
266/150排名<font color="#FF昨日变化13主题帖子积分
初来乍到, 积分 66, 距离下一级还需 84 积分
初来乍到, 积分 66, 距离下一级还需 84 积分
在线时间31 小时
不错的东西
每日推荐:
266/150排名<font color="#FF昨日变化13主题帖子积分
初来乍到, 积分 66, 距离下一级还需 84 积分
初来乍到, 积分 66, 距离下一级还需 84 积分
在线时间31 小时
哈哈哈哈哈哈哈哈哈哈
每日推荐:再做一个Android!Google发布第二代VR眼镜Cardboard
发表于 11:07|
作者Banbury
摘要:一年过去,Google在虚拟现实上的野心也开始展露,Cardboard得到升级,Google赋予其和Android一样的平价、开放的优势,同时,Cardboard SDK支持Android和iOS,构建应用可实现双目呈现3D场景,追踪响应头部移动。
在去年的Google I/O上,Google向所有与会者发放了一款名为Cardboard的纸盒版虚拟现实眼镜,相比Oculus Rift等颇为酷炫的VR头盔,第一代Cardboard着实糙得很。不过,尽管它的效果比起专业的VR设备还有一定的差距,但却也代表了Google的Geek文化和创造精神。如今,一年过去,Google在虚拟现实上的野心也开始展露,Cardboard得到了升级,除了加大本体之外,其右上方还多了颗可以搭配任何手机使用的按键,只需三步即可组装完成。同时,Cardboard SDK支持Android和iOS,开发者在构建应用时可实现双目呈现3D场景,追踪响应头部移动,Cardboard SDK for Unity则可以让开发者直接在Unity下开发iOS和Android版的VR游戏。除此之外,Google还新发布了虚拟现实内容解决方案Jump,包含Camera Geometry、Assembler和Player三大部分。Google与GoPro达成合作,由16台GoPro组成的阵列进行360°同步控制拍摄,然后再把拍摄所得交给Jump处理,处理完成的结果可以用Cardboard或其他任何VR设备观赏。Google在虚拟现实上的尝试其实惊喜不多,360°全景VR早已存在。但Cardboard却能让用户以低廉的成本享受到VR设备带来的沉浸式体验,同时以Google自己的技术标准来规范智能手机虚拟现实应用内容。赋予Cardboard和Android一样的平价、开放与整体应用,这就是Google在虚拟现实领域的优势。另一方面,苹果也在加紧布局虚拟现实和增强现实。今年早些时候,苹果公司获得了iPhone上VR头戴式设备的专利,并收购了一家成立于2003年的增强现实的初创公司Metaio,另外,苹果还在为地图应用开发增强现实功能,可让iPhone指向街道时显示附近商户。CSDN移动将持续为您优选移动开发的精华内容,共同探讨移动开发的技术热点话题,涵盖移动应用、开发工具、移动游戏及引擎、智能硬件、物联网等方方面面,如果您有想分享的技术、观点,可通过电子邮件(tangxy#csdn.net,请把#改成@)投稿。第一时间掌握最新移动开发相关信息和技术,请关注mobilehub公众微信号(ID: mobilehub)。
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章}

我要回帖

更多关于 unity3d vr游戏开发 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信