UE101 发表于 2023-4-5 01:06:05

【转载】为什么抛弃了 Addressable

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

## 外链

* (https://github.com/LiuOcean/Addressable-Example)
* (https://app.heptabase.com/w/7bda6b62ab70bc7a4a038a5e35987e32a708a812506529526a2a486809f241e1)
* (https://github.com/favoyang/unity-addressable-importer)

## 多人协作灾难

我怀疑 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` 直接加载这个路径即可从图集中拿出资源
* 资源释放方式

* 可以直接对 `GameObject` 进行释放,内部会处理这个 GO 和底层 Handle 之间的关系
* 可以直接对 `Object` 进行释放
* 可寻址功能

* 这个功能在一些情况下非常受用,比如我习惯将 UI 的加载地址简化为 Prefab 的名字,同时对应的代码也和 Prefab 同名,这样 UI 底层框架就完全不 care 这个 UI 到底要去哪里加载
*

## YooAsset

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

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

![](http://www.liuocean.com/wp-content/uploads/2022/07/16560598681831.jpg)

这里建议参考上面用 Heptabase 写的 Addressable 迁移 YooAsset 文档,按照文档中描述的设计,可以做到业务逻辑完全不用考虑任何释放逻辑,只管加载,同时保证资源一定会在最合适的时候进行释放
页: [1]
查看完整版本: 【转载】为什么抛弃了 Addressable