本文为:“入微” 2022年微信公开课PRO 小游戏专场 分享实录
分享人:微信公开课讲师 袁梓民
主 题:wasm | 小游戏新运行时能力
大家好。我是来自微信小游戏的工程师袁梓民,我今天带来的主题是:wasm – 小游戏运行时的新能力。
今天我的分享会分成两部分。
第一部分是简单介绍下 WebAssembly 及其在小游戏上的应用场景。
第二部分是关于 Unity 游戏转小游戏和案例分享,这是我们今年投了很多精力做的事情。
首先我们来看下第一部分:ebAssembly应用场景。
WebAssembly – 小游戏新运行时能力
首先介绍下WebAssembly能力,简称为wasm,这是一个最近几年产生的技术,能将强类型语言如C++/Rust/Golang编译并运行在Web环境。
这么说有点抽象,那Wasm 具体能够用来做什么呢?Wasm的官网有介绍一些场景:比如将手游的游戏引擎和代码编译成wasm在浏览器里面运行起来,再比如一个游戏里面比较重计算的逻辑用原生实现编译成wasm,而其他模块仍然是js。
左边这张图里面的坦克游戏就是Unity的一个教程,一个用C#写的游戏不需要重写就可以在浏览器里面跑起来,这也是得益于wasm能力。
既然wasm这么好而且浏览器里面的支持程度已经比较高了,为了能够让小游戏拥有更丰富的技术选型,我们也支持了wasm能力,对齐wasm标准但会多一些限制,比如只能执行代码包内的wasm。
我们统计过,小游戏内的wasm计算能力是js的3倍,这意味着一些计算逻辑比较重的的模块可以尝试改造成wasm实现会更加高效和安全性、性能,更重要的是,除了已有的H5游戏引擎,现在我们可以尝试将一些手游也通过wasm技术导出适配到小游戏里面了。
我们来看一些应用场景:首先是 物理引擎 加速。
在游戏里面,物理引擎是比较常见并且是纯运算的模块,因此我们尝试将wasm版本的物理引擎在小游戏内运行起来并且用不同的引擎分别构建测试相似的 测试用例 ,测试结果令人惊喜。
在没有JIT的iOS下,物理计算的性能有7倍以上的性能提升,这意味着,很多使用物理特性的休闲2D、3D小游戏都能够享受wasm版本物理引擎带来的性能收益。
更重要的是,我们发现像Cocos和Laya等游戏引擎已经适配了小游戏的wasm能力。
除了物理引擎,我来看一下更生动的例子,这里有两个视频:(播放视频)
右边是App运行的时候录制的,右边的视频是在小程序运行的时候录制的,差别在于右边的视频左上角有小程序标志性的三个小圆点菜单入口。
两个视频的运行效果没有什么差别,如果不是小程序的菜单入口,已经是真假难辨了,那么问题是,一个完整的APP 游戏迁移到小程序上,是怎么做到的呢,是不是需要完全重写,如果重写的话是怎么做到体验完全一致的。这就是我想说的wasm第二个应用场景,一个手游只需要经过简单的改造就可以顺利在小游戏上运行起来。
大家肯定想问,怎么才能将手游导出到小游戏上运行呢?
这就是我想分享的第二部分,有关Unity转小游戏和相关的案例分享。
首先来看下是怎么做到的:
对Unity游戏而言,从下到上来看,Unity 会依赖操作系统提供的文件系统、网络和渲染等各种能力封装完整的游戏引擎运行时,包括图形渲染、物理引擎、动画和粒子效果等各种,而我们的游戏会依赖Unity 提供的各种能力来实现游戏玩法。
Unity本身是支持构建成H5小游戏的,它会核心依赖两个能力:
第一,Unity将自己的引擎代码和游戏代码一起构建成wasm 代码,所以这依赖wasm能力,前面我们已经说了,小游戏已经支持了wasm能力;第二,游戏引擎都离不开渲染能力,在浏览器端,Unity会使用WebGL接口来渲染,这个能力微信小游戏一直都是有的;
因此Unity游戏在小游戏上运行也就可行了。
我们来具体看下几个步骤,首先是技术评估,为什么要做技术评估呢?前面说到了,从原理上来讲,我们将Unity导出的针对浏览器的工程迁移适合成适配浏览器的工程,它是有一些要求的,目前我们已经适配了Unity2018、Unity2019和Unity 2021版本,更新的版本我们也会陆续适配。
除此之外,从刚刚的原理来说,Unity导出成webgl模式本身也就有一些限制,比如说暂时不能使用 多线程 能力,比如说如果有用原生插件,需要提供原生插件原码,再比如过小游戏对WebGL标准的支持程度不是很完善等,因此并不是任何类型的游戏都适合这个方案迁移成微信小游戏的。从我们目前建联的内测游戏来看,这里提到的游戏品类都会比较适合我们的方案来转换成小游戏,比如休闲类的消除答题、动作类的 跑酷 和飞行射击等。
如果是比较重度游戏,如MMO/FPS等游戏需根据实际情况评估,当然不是说这些MMO类型的游戏不能做,并且我们也有一些游戏在调了。
技术评估完成之后就可以进行项目导出了,首先我们会提供一个Unity插件。它可以做很多事情,比如最基础的,Unity 导出的胶水层代码是在浏览器上运行的,我们会转换成小游戏需要的代码;再比如Unity默认构建出来的工程结构是浏览器需要的,而我们会一键转换成小游戏的工程结构。除此之外我们会提供资源处理、纹理压缩等各种工作。
从效果来说,左边图和右边部分是Unity工具,中间是转换插件,右边是Unity Editor,中间的窗口是转换工具,整个的还原度是很高的。
转换完成后就可以接入平台能力了,对普通小游戏而言,是调用小游戏提供的JSAPI在开发者工具内就完成了,而Unity导出到小游戏的工程代码是wasm,基本是没法二次开发的。因此我们提供了微信小游戏的服务 C# SDK,游戏要对接微信小游戏的能力只需要在Unity IDE内使用C#接口即可, 插件导出后会自动适配到小游戏。这些能力包括基础的分享能力、关系链能力、支付与广告和各种其他能力,整个开发过程都可以在Unity原先的工具内闭环完成。
在欧西上线前,我们需要做一定的调优,调优需要两部分:首先是启动问题,启动是很重要的一部分。
我们看一个普通的休闲游戏导出之后,大概代码是35M,资源是80M,我们知道小游戏是即点即玩的特性,一下子要加载100兆,这对很难接受的,所以要调优。首先是代码有35M,这是一个很夸张的数字,我们知道目前为止小游戏的首包是不能超过4M的,因此我们针对wasm能力支持了brotli压缩算法, 经过压缩后,35兆文件会压缩到6.5兆,仍然是很大,里面有很多在首场景根本用不到的逻辑。因此我们实现了一个分包能力,经过分包之后代码可以压缩到2.7M,这个已经和普通的小游戏没有太大差异了。
其次是资源,如果一下子就加载80M的资源显然是不合理的,按照小游戏按需加载的特性。
首先,要对游戏进行一定的改造,比如使用AA或者AB加载的方式使用资源、再比如精简首场景、去掉小游戏模式下不需要的逻辑等,更重要的是我们提供了自动懒加载资源的工具,这可以使得不需要对代码逻辑改动就自动懒加载资源,经过这一系列的处理,首包的资源大概是3 – 5M左右。总体来看,一个休闲游戏经过启动优化之后,首次进入的耗时大概是7- 10秒左右,二次进入的时间可以达到2 -5秒,这已经是相对理想的情况了。
再就是运行性优化,从我们的经验来看,Unity游戏在小游戏运行最重要的挑战在于内存,我们知道小游戏的建议内存是不要超过1G,因为超过1G在中低端设备可能会出现闪退的问题。我们再来看一个普通的休闲游戏的内存分布,大概是分成五部分,加起来是1.2G左右,可能面临闪退风险。运行内存的优化主要是依赖于我们提供的一些工具,比如通过压缩纹理工具,GPU内存起码可以减半,通过刚刚提到的代码分包工具,因为冗余代码变少了,内存因为减少了很多冗余代码,内存也会减半。通过各种手段组合优化,最终内存占用是800M左右,只要有2G运存的机器就可以稳定运行了。
我们已经不是第一次在相对公开的场合跟大家分享Unity游戏转小游戏相关的内容了,期间我们也在持续完善这里的工作流和性能。比如说WebGL 2.0 已经有建联游戏在内测验收游戏效果了。再比如说说一次分享的时候还没有支持Unity 2020和Unity 2021,现在已经支持了。以后我们也会不断采纳开发者的意见,继续完善这里的工作流程和性能。
说了这么多,现在我们来看一些具体的案例,第一个是地铁跑酷,右上角有二维码,大家可以扫码体验,前面说了一款迁移到小游戏大概会经历三个步骤,我们来看下每个步骤分别是怎么做的:
首先是可行性评估,这款游戏花了两天的时间,一般第一次来了解方案的,会看有什么限制,运行效果是怎样的,这算是一次性投入。
其次是转换,花了5天左右,主要做的事情一般会包括几个点:
1、资源加载流程改造,因为我们知道手游一般习惯将文件都放到本地,但在小游戏里面行不通,因此需要改成AA或者AB加载的方式。
2、部分原生能力剔除,如果游戏用了一些在webgl模式下不能使用能力,就要考虑剔除和或者换一种写法;
3、手游里面,大量高度运行逻辑,可以尝试迁移到延迟加载等各种手段。
转换完了之后是接入平台能力(基本登录、广告),这个一般没有什么卡点,针对游戏需求接入SDK即可
4、体验调优,依赖于我们刚刚提到的启动优化和运行内存进行调优,比如说用我们提供的分包工具和压缩纹理工具,当然也包含我们一起配套优化工具的时间
最终花了3周左右的时间这款游戏就在小游戏上面运行起来了,上线之后我们都觉得还原度真的很高,我们内部团队也很认可这个项目。
第二款游戏是《 我叫MT2 》。这是一个比较经典的卡牌游戏,大概2014年就发布了。
这款游戏大概是11月份左右才开始正式接入我们这个方案的,从结果上来看,安卓端大概是 两个人力花了20天左右,安卓端比较好的效果可以上线了,iOS还在持续优化中。
首先是兼容性评估,所有游戏会经过这一步,比如说原生插件要提供源码,是否支持第三方插件等,大家可以仔细查看我们的文档,就可以清楚各种限制了。
其次是游戏导出转换,这个游戏花了15天,跟地铁跑酷一样的,将资源加载异步化、将游戏场景精简和不必要的逻辑进行裁剪,跟前面提到的 地铁跑酷 类似,这个游戏复杂度高一些,所以转换时间会随着游戏的复杂度,相对应会提升。
第二大步骤,是接入平台能力,这个游戏接入登录和虚拟支付,因为接入了虚拟支付,需要做相对全面一点的测试,花费的时间长一些,大概10天左右。
最后是体验调优,主要是内存调优,也比较长的时间,它分两部分:第一部分,分包优化,分包前,代码导出后是28M,在接入代码分包之后代码处理后,变为13M,压缩后是2.5M左右,启动是比较理想的。
第二是压缩纹理功能接入,在接入工具前,纹理消耗是300M左右,接入之后可以降低150M左右。通过这两个步骤优化,这个游戏也是比较好的效果上线了。
最后一个案例是谜题大陆,是一个SLG + 消除结合类的游戏,这个游戏整体的时间花费我叫MT2差不多,这里就不细节阐述,大家同样可以扫码查看游戏效果。
最后,有关Unity游戏转小游戏相关的更多的可以扫码查看文档,文档中如果有任何疑问,也可以扫码建联我们,我们会及时给出反馈。这里也有一些更多案例,大家也可以扫码体验。
我的分享到此结束,谢谢大家!