欢迎光临散文网 会员登陆 & 注册

咸鱼的VR教程(一)-怎么在Unity考虑多平台VR开发?

2019-06-29 00:23 作者:YouSing  | 我要投稿

一、前言

    这篇文章是我搞各种VRDemo移植总结下来的经验,只能作为理论上的参考。如果你只是想快速开发VR项目,我还是会推荐VRTK(虽然没有用过)。毕竟Unity的多个VR SDK的整合,本身就是一个很大的工作量,一时半会还真解释不清。如果你有意向从头开始开发多平台VR项目,还是可以在这里参考到一些概念。

    本篇会刻意忽略不同设备跟踪方案、性能和价格等的比较。虽说是一个科普性质的开发分享,但也不能变成发烧友的VR设备导购吧。主要是一方面我没太多精力花在设备评测,一方面读者也没必要消化那么多设备参数。虽说VR设备和我刚工作的时候相比,价格已经很亲民了。但要把市面上所有主流的VR设备买下来,已经是一大笔开销。因为每个人的钱包有限,还是自己选一个VR设备做主力吧。

二、VR开发的概念

    这里先让我提出一个不负责任的说法:VR的交互实质上是体感2.0。只要了解你开发的平台的设备特性及开发套路,应该没什么东西可以阻止你的想法。

1.通用套路

    这里列举三个我觉得VR SDK最重要的三个功能:

  • Tracking(跟踪):设备的跟踪,分为3Dof(旋转)、6Dof(旋转+位移);

  • Rendering(渲染):引擎将游戏渲染成左右分离的画面,然后显示在头显上;

  • Input(输入):这里局限于输入设备的摇杆、按键、触摸板等输入;

    然后我们看看在Unity引擎里面,这些功能对应什么要素:

  • Tracking→Transform;

  • Rendering→Camera;

  • Input→UnityEngine.Input、InputAction、或VR SDK的输入接口;

    我们再回到VR设备这个层次,你会发现一切都那么简单:

  • Headset(头显)=Tracking+Rendering;

  • Controller(控制器)=Tracking+Input;

    再再回到VR设备的使用场景,这里有三种常见类型:

  • 坐下体验的VR:一般是坐在沙发上,主要交互区域是前方180度的半圆柱体;

  • 站立体验的VR:由于是站立,转向比坐下更灵活。可交互的区域变成圆柱体,但不推荐大范围走动;

  • 房间体验的VR:最自由也最容易出事的VR体验方式。可交互的区域取决于你屋子大小,同时会要求玩家设定一个游玩区域;

    而且现在Unity的VR SDK支持度,我觉得可以分成三个级别,这个会直接决定你的开发难度:

  1. 黑人问号的SDK:除了能正常点亮VR设备外,实际开发起来十分难用,有各种奇怪接口和Bug。这个现象在小厂比较多,主要是因为负责Unity开发的技术力不够;

  2. 中规中矩的SDK:和主流VR SDK的思路类似,做平台移植也方便。将来可以和Unity官方整合,或是走LWRP+InputSystem;

  3. 官方整合的SDK:经过几次磨合,大厂的VR SDK算是完全整合到Unity引擎中。你可以下载厂家SDK作为扩展库和工具库,或直接用Unity的VR功能做开发。

    现在你已经了解VR SDK的各种基本套路,接下来让我们简单地介绍两个主流VR设备类型的特性。

2.低端VR设备

    代表设备:Daydream、GearVR、Vive Focus、Oculus Go等;

    开发关键词:3Dof的Headset+3Dof的Controller*1,需要Recenter,适合坐下体验,轻量级VR体验;

    这里会把淘宝卖的VR盒子忽略掉,毕竟那些华强北性质的产品,都是“云”VR讨论的贬低论据。这类产品的重心,老早已经从手机盒子转移到低端一体机了。但通常会配备一个3Dof小手柄,满足基本VR交互需求。

    其实这个小手柄最早是出现在谷歌Daydream Viewer中,解决了低端VR设备没有实用输入的尴尬。作为当时的王者,GearVR采用侧边触摸板,也支持游戏手柄输入,但是实际体验都不好。我个人感觉当时的谷歌有一点点任天堂的味道,不光是硬件上,连软件上也是。小手柄搭配GoogleVR SDK的ArmModel,可以由旋转数据模拟出位移数据。谷歌后面推出DaydreamLabsControllerPlayground、DaydreamElements和Media App Template等示例工程,我感觉低端VR设备的交互开发,一下子上升到一个高度。

Unity的XR遗留输入帮助包,已经整合3Dof Arm Model

    像这类低端VR设备,除了屏幕显示质量,有可能会超过上一代的PC VR头显,但设备跟踪被阉割成3Dof。而且本身安卓高通芯片还是没法和高端PC硬件比,能跑的VR内容的效果也很有限。主要是原本的市场定位,就是轻量型VR体验的阉割版产品。但消费者貌似都不买账,都希望有一个完整版体验的廉价产品。看看有多少低端VR一体机的用户,额外买了Nolo设备,然后去串流玩SteamVR。其实花的钱已经够买一个WMR头显设备了,又何必为难自己呢?

3.高端VR设备

    代表设备:PSVR、Oculus CV1/S/Quest、WMR、VIVE、Valve Index等

    开发关键词:6Dof的Headset+6Dof的Controller*2(可无限扩充外设),需要设置PlayArea,重度VR体验;

    这个是VR的主战场,不同设备在控制器形态上的差异性也大。如果拿几个具有代表性的VR手柄,按照棍状到手型排列,大致为:PSVR的按摩棒、Vive手柄、WMR手柄、Oculus的Touch、Valve Index的Knuckles。目前双持手柄已经是标配了,但你是在SteamVR平台的话,可外接的设备就是五花八门,比如你在VRChat能见到全身动捕的玩家。

    游玩区域,或者叫护栏系统,是设备提醒用户超出合适范围,有误撞的风险(实际上该被绊倒还是会被绊倒,一拳砸坏显示器也是存在的)。貌似Unity也没有很好的统一API方案,也只能照用厂家的SDK工具库。

    由于我不是家里有矿,所以没法折腾这么多设备。而且工作接触比较多的是低中端设备,各种SDK对Unity支持度也不同。但由于是工作,也只能硬着头皮做开发或移植。其实专心做一个VR平台的游戏,先打打预防针,不要过度依赖厂家的SDK,后面移植还是会很快的。目前看来,SteamVR还是首选的高端VR平台。毕竟一个平台几乎所有设备都通吃,也省了开发者做移植的功夫。而低端VR设备之间的移植,如果是Unity内部集成的平台,已经是在设置上切换平台就完事了。毕竟是9102年,大部分大厂的设备都差不多在Unity集成了,快没有“导入SDK”这个概念,所以小厂还是好自为之。

三、Unity将来的VR开发预览

    我觉得Unity的InputSystem推出正式版后,基本可以告别SDK之战了。之前已经看到InputSystem的UGUI支持,而VRTK也只是民间第三方支持,以后更多的教程还是会按照官方的套路来。但不管如何,你的Unity开发的VR入口,还是会从一个名为“VRCameraRig”预设体开始。

    由于我最早接触和Unity最早内部整合的VR SDK都是Oculus的,所以VRCameraRig会以Oculus VR SDK为参考。之前也说过Tracking是VR SDK的重要套路之一,所有可跟踪的设备,会放在VRCameraRig的TrackingSpace下面。需要调用Unity VR的接口去更新对应的Transform的localPosition和localRotation。

VRCameraRig大致层级结构

    CenterEyeAnchor对应着头显,一般Unity VR会帮你自动更新Camera的Transform,而Camera的很多参数都会由Unity VR决定。如果你希望由两个Camera代表左右眼,则删除CenterEyeAnchor,新建两个带Camera的GameObject:LeftEyeAnchor,RightEyeAnchor,然后修改Camera的Target Eye。

    这边使用InputSystem的TrackedPoseDriver控制LeftHandAnchor和RightHandAnchor的位移和旋转。

    实际开发中,会需要手柄可视化显示(ControllerVisual),还有在手柄上附着一些道具。由于不同手柄的坐标原点不同,所以需要脚本去更新道具容器(Hand)的位移和旋转。而PlayAreaVisual用于显示游玩区域。

    然后你可以用Prefab Variant功能去扩展你的VRCameraRig,使用代码在不同VR 平台创建不同的VRCameraRig。而输入使用InputSystem的InputAction,然后UGUI使用官方的VR支持。

四、Unity保守的VR开发方式

    你可以使用VRTK开发,但是按照目前的趋势,VRTK会变成VR入门开发者的模板库。你需要更多功能去实现更多想法时,会逐渐摆脱VRTK的框架。由于大部分大厂的VR设备已经集成到Unity,上面的开发预览都能实现,唯一让人不快的是UnityEngine.Input这个小老弟。

    如果不想那么快用上InputSystem,我可以推荐你去参考Google的BaseActionTrigger。其实实现的思路也很简单,继承MonoBehaviour的BaseActionTrigger只有一个返回Bool值的TriggerActive函数,用于判断是否触发。然后你逻辑脚本引用BaseActionTrigger,并在Update检测BaseActionTrigger.TriggerActive()。而不同输入逻辑通过继承BaseActionTrigger的子类去实现。

    之所以这么吹Google的VR SDK,是因为把GoogleVR的例子移植到其他平台特别舒服,基本就是按照里面输入框架来。当你还在一个一个的脚本中修改输入函数时,我已经通过自定义的ControllerProvider去覆盖输入,而且直接白嫖GoogleVR的满血版UGUI的VR交互。

    吹归吹,但Google已经停止维护一些VR例子。一方面可能是大家都知道怎么开发VR交互了,一方面可能是整体VR开发热情开始疲软。其实考虑多平台开发,本身就是有点瞎操心的味道。但是一旦开始移植,代码火葬场。

说点其他的吧

    其实每个人都有小白的时候,我觉得你能熟悉查阅API文档后,你已经就是入门了。但我开发一些VR和AR后,发现API文档完全不够,甚至有些大厂的开发者网站还有交互设计文档。我之所以说VR交互是体感2.0,就是因为当年任天堂Wii开创的体感1.0时代,不少设计思路到现在VR开发也适用。想当年跟别人讨论怎么检测丢东西这个动作,各种记录运动轨迹blabla,而Google的例子直接检测一个陀螺仪数据完事,这就是你和别人的差距。

    除了设计和编程外,多平台VR开发最大问题就是平台性能问题。想当年还有做手游的开发者跟我说移动VR只需要20~30帧而已,实际上这个说法也是个笑话。虽说要达到官方的理论参数,本身就是困难的事。但不管是什么类型的开发,优化依旧是重中之重,还是且行且思吧。不过当年的HoloLens就已经支持PC串流,而且各种VR一体机串流和VR无线套件,也算是不错的尝试。而且随着5G和云游戏的兴起,以后VR开发不会再拿性能说事了吧?

    不过,最近写的东西有点多,感觉有点只写不干事了。主要最近有很多要忙的事情,所以还是等有空再做做VR小游戏,再分享开发经验,溜了溜了。

咸鱼的VR教程(一)-怎么在Unity考虑多平台VR开发?的评论 (共 条)

分享到微博请遵守国家法律