5月11日,由Unity主办的行业开发者大会Unite Shanghai 2019在上海国际会议中心召开,作为推出过《鲤》、《不可思议之梦蝶》的天津队友游戏的制作人,李喆就分享了团队把《不可思议之梦蝶》从 PC 版移植到 Nintendo Switch 的经验和心得。
以下为游戏陀螺整理的演讲实录:
手柄适应性、存档、声音格式、插件等方面,《不可思议之梦蝶》的处理方式
先说一下基本的开发,Switch需要大家提前知道一些知识,不能用标准的Unity Input来做,我们用了一个插件Rewired,这个可以适应任何的手柄,我们还用了HD振动,还运用了Joy-Con等5种输入方式。玩过Switch平台都知道,Switch两个手柄是可以拆出来变成两个手柄,然后它的按键位置都会发生变化,你要知道所有方式并对游戏设计做好很好的规划,像《不可思议之梦蝶》是不支持Joy-Con Left和Joy-Con Rirght。
《梦蝶》有大量的动作解谜要素
接下来是存档问题,存档文件都是有读取要求的,需要根据范例重写I/O部分来做。在奖杯系统里面,做的PC版本是有奖杯系统的,大家会收集奖杯去玩游戏,这些奖杯在任天堂平台都没有,我们要自己制作弹窗和展示。
在声音格式方面。像Switch平台支持Opus格式硬解压,使用的Wwise可以支持OpusNX格式。它自带功能有很多,这个很多平台的声音都是可以的支持,也可以对Switch平台有一个格式,甚至可以调用硬件,这个有一个压缩格式,是可以直接压缩进入内存的,在运行时占用内存会更低一些,如果做的游戏没有考虑内存问题可能会爆掉。
还有使用插件,像Wwise和Rewird是需要考虑授权和版本问题,像Wwise根据不同平台有折扣,Rewird是免费的,是一次性支付可以使用的,在打包时并没有针对平台代码。这个代码怎么获得的,你要通过任天堂开发后台提交申请,是由任天堂提供给Wwise的开发商,再通过Wwise开发商提供信息给到你,这个东西是没有技术难度,是有时间考虑的,像Wwise是需要两个工作日的。
如何选择Unity版本?
上面说的是一些具体基础上的经验。再说一下遇到的问题,这些问题如果没有动手做过,几乎是想不到的。如何选择Unity版本?这个版本随着SDK版本变化,你提交游戏的Unity版本要求很高,如果项目没有达到要求的最低版本的话提交就会失败,是会被拒绝的。我们遇到一个问题,可能有时候打包出来的游戏在Switch出现一些崩溃问题,而且只有非常少的信息提供给你,你去开发者论坛搜索根本就没有任何线索,我们要尝试切换一下更低版本,去测试这个打包是不是正常。我们的遭遇是,一开始是用2018.1.1去开发,开发时都是正常的。再切换到2018.1.9直接打出来的Rewird就是正常的,大家也可以分享一下经验,也许有其他办法可以直接解决。
如果用两个版本,比如说我开发功能,可以去调试,像《不可思议之梦蝶》游戏是56G,每次开发版本要重新导入其他资源,如果你在SSD硬盘导入一遍遍工程需要一个多小时,完全接受不了这个时间,所以就可以加入一个Cache Server,但是时间还是长一些,最后又想出了Git,这种方式是最快的。
通过修改声音格式,从90秒的载入时间,减至30秒
关于载入时间,Switch平台存储实际上是用的一种慢速的存储方式,像《不可思议之梦蝶》这种的游戏,第一关载入时间大概在90秒左右,你可以做一些载入动画什么的,这个时间还是太长了,没有办法忍受,我们只做一个东西就变成了30秒。这里我要提一个非常有名的游戏——《ICEY》,这个在发布时我正好和他们在办公室聊天,就发现程序员一直在调试,他发现游戏启动时太慢了,整个游戏前60秒都是黑屏的,很难调试。
另一款独立游戏佳作《ICEY》
其实我就突发奇想,要不改一下声音格式,他就切了一下,直接就从60秒变成了十几秒的载入时间,瞬间可以接受了。因为《ICEY》是有很多的语音声音文件,打包还是在文件夹底下的,所以要把所有都载入内存。这种方式对Switch有压力的平台有更好的优化方式。
我们还遇到一个问题,第一次播放声音时有一个卡顿延迟,但是反复播就没有了。我们通过将《不可思议之梦蝶》这个游戏声音的加载改成流式加载就可以将加载时间从90秒减少到到30秒,用最小的事情产生最好的结果。还有一个Wwise可以把不同音效打在不同的SoundBank里面,还有一些共同的音效可以打在公共的Bank里面,可以通过这种方式再次减少游戏运行时的这种声音资源带来的压力。
烘焙工作,可以大幅度减少包体容量
在包体尺寸的优化方面,Switch并没有太大的要求,我们也是顺便优化一下包体,主要的优化方式是用Console和Open Editor Log来做的,你很难发现是不是打入包里了,有些资源觉得根本没用,会通过材质球还会进入包的安装部分。所以通过这个东西完全清楚看到哪些在包里,哪些是不在包的,肯定要把包里的东西进行重点优化。像Switch平台是支持ETC2和ASTC这种模式的,会很快速载入的,你在压缩会产生非常大的压缩率。找到纹理之后去覆盖平台设置,可以切换不同压缩格式,压缩格式也不是越小越好,因为压缩的纹理是有显示效果的损失。
大家要平衡最终的显示效果和包体体积的关系,如果烘焙了,你可以对平台单独设置,这样可以大幅度减少包体容量,这些东西也可以很明显察觉到阴影的显示变化,你需要考虑在体积跟质量之间获得平衡。其实Switch的掌机平台是比较低的,下降一些不会有太大变化。
还有一个是比较容易忘掉的,Mip Maps,这个在后期迭代时会把贴图做得比较大,会做1024*512这种模式,如果把Mip Maps勾掉的话会有很多能量,所以不会产生实际上的效果。
整体看下来打包之后是1.8G,这个不是实际打包的,你看Android打包出来容量是这个,在里面还会继续压缩。像Switch压缩打包结果应该在1.2G左右,后续还会有一个打包压缩,在机器上就会占到1.8G的容量。
排第一的是60Mb、40Mb、25Mb,我们并没有进行太多处理。第二位是otf,支持多语言的,你要有特殊字体放进去,每个字体都有容量,针对中国,不支持多语言切换的话都可以删掉。第三,Fbx文件,里面有很多动画,都是比较大的。
最后说一下Levels,《不可思议之梦蝶》场景里有很多Mesh,它的存储不会占用太多的地方。为什么需要优化呢?你就算切换到静态模式的话,静态合批会被动态物体打断,你在Framedebugger里面可以看到是被打成一段一段的。这个DrawCall数非常高,对CPU压力非常大,这个东西在PC是几乎没有影响的,在Switch平台和移动平台压力是非常大的。
我们做了一个合并工作,就是烘焙工作,我们通过第三方工具来做的,叫做MeshBaker,非常有效果。你可以把想合并的静态的Mesh选入进去,在工具里去设定每个球的半径大小,这个球半径包含的都可以形成一个簇,可以通过MeshBaker自动合并。为什么合并呢?因为在运行前就已经处理好了,再有一个就是说遮挡剔除功能,在摄像机渲染上是可以直接拿掉的,这个可以极大的提高渲染性能,这是合并Mesh的目的。合并Mesh之后有一个结果可以让场景变得非常大。大家可以想象一个石头大概有100面,我这个场景里面石头块有1000个,我分的时候板这一块地方一共会有50个物体,会合成一个,合成一个之后原来Mesh的就不用了,就单独形成了一个顶点数新的模型,存储容量会大幅度提升,会变得非常大。为了提高渲染性能,为了整体的结果,你肯定是要丢失一些东西。在纹理压缩上做了很大处理,让出了很多空间。纹理从一开始,没有优化之前,就包括所有的Levels加起来有2G多,这是非常大的减少包体的办法。
渲染性能方面,不仅要考虑显卡,还有CPU问题
提升渲染性能。大家玩的3D游戏多了之后只认为显卡对游戏性能比较大,我问过很多开发者,其实项目一开始优化时,CPU跑不动带来的结果几乎都是百分之百的。一般都不会去考虑CPU问题。它有一个单独的工具,叫做NxGraphicDebugger,这个使用起来和他们差不多。我们通过自己的努力优化,没有针对游戏有改动,可以从Switch平台优化起来,我可以跟大家分享一个经验,Unity打包出来的程序,如果使用Standard Shader,在Switch平台到底能运行几个Cube?就在动态物体,不是静态物体,最后测下来只能运行6个,超过6个之后就不能稳定在60帧了。所以大家在Switch,在掌机模式下也不用求60帧,我觉得30帧就已经不错了。
在使用第三方插件时,一定要先把插件关上,看看游戏到底能不能运行,有没有问题,我们一开始闪退花了3-4天,是发现插件的原因,而且第三方引擎库输出是非常少的,其实是完全一个瞎调试的状态。后来通过项目经验开始关东西,最后排除发现是第三方插件的问题,就可以折半查找,关掉之后看有没有问题用快速查找来看有没有问题。
这是在一个星期之后,还是这个场景,大家看到全功能已经跑起来了,已经可以稳定在30帧以上了,就是这么一个状态。这个过程之中经历了太多太多的调试和处理,最后再经过大概一个月的时间,我后来后来安排了程序员做全职工作,后来整个《不可思议之梦蝶》每个场景都可以稳定在30帧以上,有一些东西其实再说一下经验。比如说Switch可以归为移动平台,经过我们调试,像后处理的屏幕AO等占用都是比较大的,最后一定要想替代方案。
我要找游戏陀螺:
商务合作/采访/投稿:
西瓜(微信号 18659030320)
刘威(微信号 18948723460)
文静(微信号 mutou_kiki)
行业爆料:boq(微信号 boq270756)
投稿邮箱:tougao@youxituoluo.com