44. Unity转小游戏总结

总结下最近公司先后两款游戏(《巨星:足球崛起》,《夺笋高手》)转成小游戏的一些经验。第一款游戏是我转的,第二款是在我转的经验基础上,其他同事转的。因为第二款游戏会复杂点,所以也遇到了很多问题。

游戏层修改

资源不放在Resources下

Resources下的资源都会被打在首包里面,如果资源都放在Resources会导致首包很大,首次进入游戏下载会很久,所以不建议把资源放在Resources下。

资源打包和加载

因为资源涉及到下载过程,并且因为小游戏是单线程的,一些同步加载的接口可能会导致整个游戏卡住了,所以资源加载方式只能是异步方式加载。

我们小游戏使用了第三方的资源管理库YooAssets来管理所有资源打包和加载。也可以使用其他第三方库或者Addressable来做。

资源打包的力度不要过大,一个是过大不利于资源卸载,另外一个是资源下载的过程中会占用内存,如果下载过大的内存会容易导致崩溃。

另外资源加载改成异步的时候要注意一些Bug也会随之产生,我们这边比较容易出问题的地方是优化的滚动条中的内部Item在异步加载资源的时候会出现资源错误的情况。

不支持的一些接口

官方明确给出一些不支持的接口,可以详细看看,如果有不支持的内容可以找找替换方案。

我们这边需要修改比较多的地方是网络和文件接口。网络就改成用Unity下的接口就行,文件需改成WX下的接口。如果使用了Syste.Net下发起Http请求的话,游戏会直接卡死,并且不会有报错。

优化

性能优化方面有很多,我们做的不一定都适合其他项目,所以建议还是把官方文档上关于优化的文档都看一遍,当我们实在没思路的时候文档也会重复多次阅读相关文档看看有没有遗漏的优化项。

算力优化

因为平台问题所以小游戏下面的性能会差点,官方给出的测试结果是native下的1/3性能。所以如果比较靠算力的游戏可能需要进行这一方面优化,主要优化思路:

  • iOS开启高性能模式
  • 减少内存分配(使用缓存)
  • 减少算法时间复杂度

内存优化

这一块是我们的卡点,花了很多时间去研究这一块。

1. 升级Unity并使用ASTC压缩格式

把Unity升级到2021版本,支持ASTC(可以节约很多内存)图片压缩格式的同时,也解决了我们之前Unity 2020的时候内存会不断上升的问题。

2. 充分使用插件提供的工具

插件提供资源压缩工具,可以检测项目里面的图片的使用情况,按照文档操作优化即可。

3. 代码大小优化

代码大小可以大大减少小程序编译优化所占用的内存,一开始我们不太了解,这一块踩了很多坑。

  • 删除不必要的第三方插件
    项目中用到的插件如果使用范围很小并且代码量也很大的话,就及时找替代方案,我们代码里面删除了一个Best Http,是我们的代码包少了2M

  • 代码裁剪
    Player Settings -> Other Settings下,打开Strip Engine Code并且裁剪级别选择最高

    设置了这些选项之后会有找不到class的报错,这时候我们需要通过link.xml去把这些找不到class主动包含进去。

    找不到class的报错一般有两种,第一种是引擎的class找不到,这种不会直接给出类名,一般是给一个class id,例如:

    这种可以参考官方给出的文档,把class id对应的类加到link.xml里面。

    第二种是逻辑层的class找不到,这种会直接给出类名,同样加到link.xml里面即可。

  • 关闭异常捕获
    这个比较看重代码质量,因为关了异常捕获功能,一旦有异常游戏直接崩溃。我们游戏DoTween安全模式给我们捕获了很多错,处理起来太麻烦,所以我们游戏没法关闭异常捕获功能。

    关闭方式在 Player Settings -> Publishing Settings下

  • 使用代码分包
    使用插件提供的代码分包工具进行操作即可,这里吐槽下,使用的服务器应该比较差,有时候等了一个小时才分包好。

  • 重新建一个工程
    我们自己测试新建一个空的工程,把Assets下所有文件拷贝到新工程,解决掉一些依赖问题之后打出来的包也少了几M。应该是某些没用的第三方依赖库一直被包含着,换新项目之后这些被删了。

我们游戏最终代码大小从一开始的38M,降到了26.8M。编译之后的内存占用从800M降到了500M左右(iOS)。

4. 其他内存优化

  • 模型禁止读写

问题

渲染问题

渲染问题比较多,一些Shader在Android或者iOS上会显示不正确,这个暂时不知道原因。

首包黑屏/花屏问题

测试发现我们从编译完的loading页面进入到我们游戏loading界面时候会有黑屏/花屏的情况。

原因是我们首个场景没有摄像机缘故,给一个默认背景图之后两个loading切换就变得很丝滑了。