manaijin 发表于 2023-4-28 10:06:36

Addressables基础工作流

原文链接:https://zhuanlan.zhihu.com/p/588120058


## 一、综述 & Start

### 1.1 综述

Unity默认的资源打包发布方式是AssetBundle,Addressables在AssetBundle的基础上,处理了资源在项目整个流程中的管理。具体涉及资源打包、加载与卸载以及热更。传统的AssetBundle对于资源管理来说相对繁琐,主要体现在以下几个方面:

* 资源打包的冗余问题
* 资源打包的方式不直观
* 中间有很多细节(比如资源进首包,需要将ab包放到StreamingAssets目录下,再移除以避免Unity重新加载)
* 资源依赖的问题
* 资源热更新方案(增量更新、文件对比、资源下载状态……)
* 同步与异步资源加载
* 内存~Profiler
* ...

对于比较成熟的项目来说,通常已经有一套完善的工具链,可能对于部分打包步骤不太直观方便,但整体流程较为完善,一般也不用考虑Addressables。如果是在项目前期,Addressables可能是一个不错的工具,其功能特性如下:

* 提供GUI的方式对资源打包进行管理,不需要频繁修改打包代码,对资源管理更加便捷
* 提供了加载实体AB包的开发模式,能够模拟真机的资源加载方式
* 资源依赖处理(打包、加载)
* 傻瓜式的资源查询、更新方式(优劣参半),随用随下
* 打包检测工具

### 1.2 Start

(1)安装

![](https://pic4.zhimg.com/80/v2-f5c7828ff4477d55ed3f0424479bbb47_720w.jpg)

(2)拉取Package到本地

在Package Manager中拉取的内容是无法修改的,若需要修改源码,则需要将Cache文件夹中的缓存放到Package(包括依赖package)

![](https://pic4.zhimg.com/80/v2-5ebe5679e1d34011f99af8fb77a720cf_720w.jpg)

(3)标记资源:将资源或文件夹放入对应Group即可

![](https://pic2.zhimg.com/80/v2-e63cf8af96604cab569e80f64d9a5c35_720w.webp)

(4)配置Profile

![](https://pic1.zhimg.com/80/v2-8953d6a4d1c55f5e8fbc3dbdceed523c_720w.webp)

只需要配置远端路径(Http服务可使用Addressables自带的Host Services,但建议使用HFS方便测试)

(5)发布资源

![](https://pic4.zhimg.com/80/v2-bdab135bb86c00d7e5d3c9808bc89fe7_720w.webp)

Addressbales提供了两种资源发布模式:全量发布;增量发布

(6)选择Play Mode & Start

![](https://pic3.zhimg.com/80/v2-f582c59b96f7b491d1e579e81cceb012_720w.webp)

fastest模式通过AssetDatabase加载资源,Editor下不需要发布资源。Existing Build会真实得加载AB包,Editor下需要打包资源。

```text
// 下载preload1资源
Addressables.DownloadDependenciesAsync("preload1");

// 加载key
Addressables.LoadAssetAsync("Cube");
```

## 二、Settings

### 2.1 AssetGroup

Addressbales以GUI的方式较为便捷得对资源进行分组打包管理。默认每个分组的资源文件存在于AddressableAssetsData/AssetGroups目录下,分组可以使用相同策略对资源批量管理。

![](https://pic3.zhimg.com/80/v2-b18da78eafc5d7f25118d58b47c4963a_720w.webp)

![](https://pic1.zhimg.com/80/v2-927be932a8d45d8ab71651d729ce8950_720w.webp)

选中Group可以看到其属性面板。Build & Load Paths定义Group的打包与加载路径,该路径可在Profile中修改。包体分为本地包与远程包。

![](https://pic2.zhimg.com/80/v2-cedc7e1495d738171f899ad61c414a59_720w.webp)

Group提供三种压缩方式:无压缩、LZ4、LZMA。LZ4包体大小中等,解压较快,可以只解压部分资源;LZMA包体较小,但解压资源较慢,只能将资源全部解压。通常选择LZ4。

![](https://pic3.zhimg.com/80/v2-c9d3f4c1946e325b816b463fb92e081e_720w.webp)

* Include in Build是指构建时是否包括此Group。
* Force Unique Provider自定义的Provider实现,则需要勾选,自定义Provider(不在组间共享)。
* Use Asset Bundle Cache表示是否缓存下载的AB包,不缓存的话每次都要下载。
* Asset Bundle CRC表示加载资源时是否进行CRC校验文件准确性。
* Use UnityWebRequest - 表示使用UnityWebRequestAssetBundle.GetAssetBundle接口代替AssetBundle.LoadFromFileAsync接口去加载本地资源。不建议勾选

![](https://pic4.zhimg.com/80/v2-d7452bfdff15969a0fb6a6283e06f173_720w.webp)

* Request Timeout:链接超时后,进行Abort操作。此处表示超时的second
* Use Http Chunked Transfer(在Unity2019.3+已经被废弃,不建议勾选)
* Http Redirect Limit:使用UnityWebRequest下载资源时重定向的次数
* Retry Count:下载失败后重新尝试下载的次数

![](https://pic4.zhimg.com/80/v2-0927a2088814274d690058ae44d75c3f_720w.webp)

这三个选项表示打包时,是否将资源的Address、GUID、Label写入包体中。对于有分包更新需求的情况下,建议都勾选上。

![](https://pic4.zhimg.com/80/v2-9cd41a394f0bcac7b568a17b64ca4f43_720w.webp)

Internal Asset Naming Mode:如何为内部asset命名

* Full Path:用完整路径
* Filename:资源的文件名
* GUID:用GUID串
* Dynamic:Addressables根据组内的资产选择最小的内部命名
* Internal Bundle Id Mode(如何为内部bundle命名):
* Cached Clear Behaviour:空间不足时清理Cache;有新版本资源时,清理Cache
* Bundle Mode:打资源的策略

* Pack Together:根据Group打包
* Pack Separately:每个文件打一个包
* Pack Together By Label:根据Lable进行分包
* Bundle Naming Mode:如何创建bundle的名字

Asset Load Mode、Asset Provider、Asset Bundle Provider通常不用修改,这三个选项用于控制asset的加载方式、AB包的获取方式。如果存在自定义的处理方式,可自行选择。

![](https://pic3.zhimg.com/80/v2-93801f60953e6299c9379b508918b2a6_720w.webp)

### 2.2 AddressableAssetSettings

Profile定义了各种路径参数,切换不同的路径以灵活映射到的路径。(修改路径后需要重新Build资源后才能生效,因为locator的下载路径是在Build时序列化到本地的。体验上不太舒服~~)

![](https://pic2.zhimg.com/80/v2-ea6cb74731f512c118db4c107e104e8d_720w.webp)

* Send Profiler Eevet:向Event View 窗口发送事件,以监听资源加载状态
* Log Runtime Exceptions:发生错误时,Addressable内部会抛出异常

![](https://pic4.zhimg.com/80/v2-242dd334e21180ed98c71a3e8cf1ef13_720w.webp)

* Player Version Override:默认Catalog的命名是Catalog_<timestamp>.json,如果配置了该项可能会影响catalog名称。若发布客户端后,修改此项发布资源,则原客户端不会检测到存在资源更新。
* Compress Local Catalog\Optimize Catalog Size:优化Catlalog文件大小,通常不会勾选,除非此文件影响流程体验。
* 当需要发布远端资源时,勾选Build Remote Catalog
* 当需要手动更新远端资源时,需要勾选Build Remote Path & Only update catalog manually(不勾选的情况下,也不是每次都下载hash文件进行对比,保险还是手动下载)

![](https://pic4.zhimg.com/80/v2-149bf510a89dd9f8d32d57e32ce4ebff_720w.webp)

* Player Version Override:资源版本id
* Check for Update Issues : 点击Addressables Groups/Tools/Check for Content Update Restriction的处理方式。(将静态资源修改放到一个新包中,通常用于对Local资源的修改)
* Content
State Build
Path:Addressables第一生成资源时,会生成addressables_content_state.bin文件,用于对比记录后续资源更新时的内容。该文件默认存储于AddressableAssetsData/Windows

![](https://pic3.zhimg.com/80/v2-5f6e2a62479020ff56faf7868ecbf32e_720w.webp)

* Custom certificate handler:自定义证书验证,继承(https://link.zhihu.com/?target=https%3A//docs.unity3d.com/2019.4/Documentation/ScriptReference/Networking.CertificateHandler.html).
* Max Concurrent Web Requests:最大的Web请求数量
* Catalog Downloaded Timeout:下载catalog文件超时时间

![](https://pic2.zhimg.com/80/v2-bef5b5a1d32f2728b05b4ac7fe3baaf9_720w.webp)

* Ignore Invalid / Unsupported Files in Build:忽略打包时的无效资源(测试.bin属于无效文件)
* Unique Bundle ID:使用此设置可以在资源已经被加载进内存之后依然支持动态更新资源。其代价是在更新资源时,引用修改的资源也会被更新。不建议勾选。
* Contiguous Bundles:优化打包时的资源时序,提升资源加载速度。(Addressables 1.12.1以前的版本想要减小包体,不要勾选)
* Non-Recursive Dependency Calculation:开启该选项可以提高构建速度同时减少运行内存的占用,但资源存在循环依赖时会导致加载失败。不建议开启。
* Shader Bundle Naming Prefix:Unity内置Shader Bundle命名,建议Project Name Hash
* MonoScript Bundle Naming Prefix:MonoScripts生成的Bundle命名,建议Project Name Hash
* Strip Unity Version From AssetBundles:是否移除Bundle包头的Unity版本信息(Unity版本不发生变化的情况下,可以勾选)
* Disable Visible Sub Asset Representations:在不使用Sub Asset(Sprites、sub-meshes)情况下可以提升打包时间

![](https://pic2.zhimg.com/80/v2-6aa973b716ae4dfcd91c9a3e2456ba55_720w.webp)

Addressables提供了三种Editor下资源加载方式:Use the Asset database(Asset database加载)、Simulate groups(模拟Group处理)、Use existing build(加载实际包体资源)

![](https://pic4.zhimg.com/80/v2-0ab4ab74b2917f61b6b8701d316c5e4b_720w.webp)

* New Build/Default Build Script:默认方式构建资源
* Update a Previous Build:增量式更新资源
* Clear Build Cache:清除构建的资源缓存(只是清除了link,实际目录下的资源还在)

![](https://pic1.zhimg.com/80/v2-87dc08c2df8e5c29ca7c256d8a29b3ec_720w.webp)

## 三、打包处理

### 3.1 打全量包

处理步骤如下:
(1)根据需求配置Group的构建路径(Remote\Local)
(2)根据远端路径(CDN\HFS)修改Profile,选择需要的Profile
(3)修改资源版本号(如果只是本地测试不需要,但若是正式发布需要修改,避免影响老版本)
(4)点击New Build/Default Build Script进行资源打包
Profile定义Build和Load路径,若需要从多个项目加载资源的情况(比如美术、Scene单独分离出工程进行制作),可以定义不同的Profile以满足需求。对于大部分工程来说,通常不需要修改local资源相管路径,这些工程会构建到相同的目录中。
注意:路径字符(以及自动生成的子目录)长度限制在260个character,否则会构建失败

默认的local build路径:Library\com.unity.addressables\aa\平台\系统
默认的local load路径:Editor模式与构建路径相同;实机运行时被解析为StreamingAssets目录
Build输出文件:

* .bundle:对应于Group设置的local资源
* settings.json:运行时Addressables的配置参数
* catalog.json:资源列表数据,用于查询资源更新
* AddressablesLink/link.xml:将我们本地构建的group、address、label等key与具体资源关联文件。在2021.2之后的版本,若不存在该文件,则会复制AddressableAssetSettings.ConfigFolder或者
Assets/Addressables_Temp目录
* Library/com.unity.addressables/AddressablesBuildTEP.json:构建性能数据,参考 (https://link.zhihu.com/?target=https%3A//docs.unity3d.com/Packages/com.unity.addressables%401.20/manual/BuildProfileLog.html)
* Library/com.unity.addressables/buildlayoutreport:构建日志,参考 (https://link.zhihu.com/?target=https%3A//docs.unity3d.com/Packages/com.unity.addressables%401.20/manual/BuildLayoutReport.html)

注意:使用默认的local路径,在构建应用时,Addressbales会将打包资源拷贝到StreamingAssets目录,在应用构建结束后再将资源移除。如果使用自定义的local路径,需要自己处理这一过程。

默认的Remote Build路径:ServerData\平台
默认的Remote Load路径:为实际的下载url,必须要启用相管服务(CDN\HFS)后自行定义。
构建的文件:

* .bundle:对应于Group设置的远端资源
* catalog_{timestamp or player version}.json:记录最新的资源版本。此文件命名与时间戳或者资源版本号有关系,命名方式在AddressableAssetSettings中设置。
* catalog_{timestamp or player version}.hash:用于检查catalog文件是否发生变化,通常程序启动时都会下载这一文件。

除了以上资源,打包资源时可能还会生成`unitybuiltinshaders` 和`MonoScript`AssetBundles。如果构建中使用了内置资源会产生前者,MonoBehaviour对MonoScript存在引用,里面包括了定位某个具体类所需要的信息。

### 3.2 打增量包

全量包会重新构建所有资源,当我们只需要对一部分资源修改时,这会产生很多不必要的工作。Addressbales提供了根据资源更新记录进行增量式更新

![](https://pic3.zhimg.com/80/v2-bfd40a4aa0a2df72924b1ee18d596152_720w.webp)

需要注意的是,能够进行增量式更新的前提是存在addressables_content_state.bin文件,并且不能修改资源版本号。此文件记录了资源的状态数据。当我们构建全量包时,会在“Assets\AddressableAssetsData\平台”创建该文件,一定不要手动修改此文件。只有相同版本号的catalog才会检测差异,从而更新。

![](https://pic4.zhimg.com/80/v2-296092d88f7fb1439fe5f5c1938622a7_720w.webp)

addressables_content_state.bin

![](https://pic4.zhimg.com/80/v2-7d33be87b5c5be857f70e4f3b7575f3f_720w.webp)

## 四、运行时的资源

### 4.1 资源加载

Addressables提供了通过address、label、AssetReference以及IResourceLocation进行资源加载。在执行异步操作时,会执行以下流程:

* 将key转换为IResourceLocation
* 根据catalog查询资源依赖
* 若相关bundle都存在则直接加载,否则会先从远端下载
* 将加载的资源赋值给AsyncOperationHandle.Result
* 设置AsyncOperationHandle.Statue并执行Completed事件

若加载失败,相关信息会存储在AsyncOperationHandle.OperationException。默认情况下,加载失败不会抛出异常,如果需要可以为ResourceManager.ExceptionHandler设置回调。此外还可以通过设置抛出异常。

![](https://pic2.zhimg.com/80/v2-92642ca4d4fcb347167209e85ae5d179_720w.webp)

### 4.2 资源卸载

通过(https://link.zhihu.com/?target=https%3A//docs.unity3d.com/Packages/com.unity.addressables%401.20/api/UnityEngine.AddressableAssets.Addressables.Release.html)可以卸载资源、实例、handle。释放handle可以减少资源的引用计数,并且handle会失效。如果不需要使用回调结果,某些API接口提供了自动的handle回收参数,例如(https://link.zhihu.com/?target=https%3A//docs.unity3d.com/Packages/com.unity.addressables%401.20/api/UnityEngine.AddressableAssets.Addressables.UnloadSceneAsync.html)。
即便handle回调失败了,仍然需要对其进行释放。通常情况下,Addressables会自动释放Operation失败期间的资源,但手动释放handle仍然是有必要的。
Addressables.LoadAssetsAsync是无法取消的,但如果在操作完成之前释放对应的handle,会减少对handle引用,在资源加载完成后会自动释放。
页: [1]
查看完整版本: Addressables基础工作流