个人使用和关注 Addressable 有段时间了,对 Addressable 的缺点容忍了很久,最终在一次打包时加班到 11 点后,决定彻底舍弃 Addressable 这个 ab 方案

外链

多人协作灾难

我怀疑 Addressable 的设计团队,从最开始压根就完全没有考虑任何多人协作的问题,导致只要多人开发,你不做任何处理,完全就是灾难,好在我们可以通过一些流程上的限制,来避免大部分多人协作的问题

自动 Import

这里就要用到 Addressable-Example 仓库中使用的方案了,其大致思路是,所有的 Group 只在本地生成,不参与版本管理,每个人本地各自有一份,这样即使整个配置崩了,全部删掉重新 Import 就好了

之前听说一些项目是手动拖资源到 Group 中的… 有点难以想象…

git hook 禁止提交

但是这样依然不够,只解决了 Group 的动态生成,在版本管理中 AddressableAssetSettings.asset 是一个更特殊的文件,即需要参与版本管理,又不允许任何人提交,此时就需要借助 git hook 来解决这个问题

大致流程就是每次 Unity 启动时,判断 hook 文件是否有变化,有就覆盖一份,hook 文件中检查本次 commit 的文件是否包含了不期望提交的内容

Missing Reference

这样下来,禁止提交的功能也好了,但是仍然不够!Addressable 在某些情况下会出现某个资源 Missing Reference,导致不能工作,此时完全删除整个 Group 重新生成也能解决这个问题,这里我是直接修改了 Addressable 的源码,具体可参考仓库

资源地址撞 key

这个问题比较奇葩,我大致总结出来一个规律,左边开着 Unity,右边 git pull 更新仓库时,在某些情况下,Addressable 可能会将同一个资源统计两次,这个就非常离谱了。 Group 面板里面一大堆资源,有一个重复了,找也找不到,运行游戏就报错,报错就告诉你 key 重复,也不知道谁重复了

碰到这种问题,如果没有使用自动生成 Group 那可就太惨了…

噢对,上面的 key 重复的报错,Addressable 会把异常吞了,没有任何堆栈,就只有 key 重复

源码异常难懂

我至今不理解 Addressable 底层为何要如此设计,明明是一个很简单的功能,却设计的如此复杂难懂,上面那个吞异常的问题,我自己一点点的 Debug 找了很久才找到关键位置在哪里,后面自己改了一下报错的日志

偶现的首包 ab 错误

这个问题也非常奇怪,偶尔在打包时,首包的 ab 怎么都加载不出来。但有时候又是好的,这个问题可能跟我之前的打包流程有关,但后面抛弃了 Addressable 后就没再深究了

https 校验问题

之前被这个搞的也很头大,在部分机型、部分情况下,同一个 CDN 服务器和 ssl 证书,ssl 证书为了避免版本问题,将 1.0~1.3 (大概是)全部兼容了,但仍会出现 ssl 校验失败导致无法下载的情况

我后面还试过自定义 ssl 解析,手动处理 ssl 校验过程,也会出现校验失败,或者强制返回 true,也不行,非常离谱

动态切换 CDN 源

具体需求是,同一个包,可以通过服务器下发的内容动态切换 CDN 源,比如当前客户端需要从 1.0.0 中对应的版本切换到 1.1.0,此时需要对比差异更新,而不是全量更新

我自己测试时,虽然也可以动态切换 CDN 源,但是无法做到对比差异更新,虽然也可以自己修改源码实现这个问题,但到了这种程度继续使用 Addressable 已经没有意义了

Addressable 做的好的地方

在和其他 ab 工具横向对比上,Addressable 还是有很多做的不错的地方

  • Editor GUI 比其他大部分 ab 工具都要好
  • 仓库地址的配置方式
    • [] 代表反射取值,Build 时存放
    • {} 代表反射取值,Runtime 时存放
    • 这个功能非常方便,很受用
  • SpriteAtals 的加载方式
    • Assets/Res/xxx.spriteatals[100] 直接加载这个路径即可从图集中拿出资源
  • 资源释放方式
    • 可以直接对 GameObject 进行释放,内部会处理这个 GO 和底层 Handle 之间的关系
    • 可以直接对 Object 进行释放
  • 可寻址功能
    • 这个功能在一些情况下非常受用,比如我习惯将 UI 的加载地址简化为 Prefab 的名字,同时对应的代码也和 Prefab 同名,这样 UI 底层框架就完全不 care 这个 UI 到底要去哪里加载

YooAsset

途游旗下的 ab 解决方案,整体非常省心,我迁移 Addressable 到 YooAsset 大概就用了两天时间,大部分时间还是在读 YooAsset 的源码

得益于最开始封装 Addressable 的加载时,考虑到了后续可能会整体换掉 ab 方案,所以在 API 的隔离设计上做的很彻底,业务逻辑无法直接使用任何 Addressable 相关的 API,统一使用了一个类似垫片一样的调用方式

这里建议参考上面用 Heptabase 写的 Addressable 迁移 YooAsset 文档,按照文档中描述的设计,可以做到业务逻辑完全不用考虑任何释放逻辑,只管加载,同时保证资源一定会在最合适的时候进行释放


What doesn’t kill you makes you stronger.