在 2018 版本,Unity 推出了 Addressables 系统,主要用于项目中资源的组织和打包,以及运行时资源的加载和释放。目前,经过了几个版本的迭代,Addressables 已经非常稳定,能够自动处理复杂的依赖关系。只需要将资源设置为可寻址,就可以简单的通过一个地址从任何地方加载并使用它。
使用 Addressables 会带来以下好处:
- 灵活:可寻址可以使得资源位于任何位置,并且可以随时更改
- 便捷:使用可寻址系统不需要自己编写 AB 包的管理逻辑
- 依赖管理:系统会自动处理资源所需的依赖关系,无需手动处理
- 内存管理:系统会自动卸载和加载资源,并自动进行引用计数
- 内容打包:系统会自动处理复杂的依赖链,并有效地打 AB 包
安装 Addressables
Addressables 是 Unity 的一个 Package,可以通过 Package Manager 进行安装。安装之后,打开 Window
> Asset Management
> Addressables
> Groups
窗口进行初始设置。
点击 Create Addressabels Settings
将会在 Assets 目录下创建一个 AddressableAssetsData
文件夹,用于存储配置信息以及对资源的跟踪。
标记可寻址资源
将资源标记为可寻址非常简单,有以下几种方式:
- 在 Inspector 面板中勾选
Addressable
选项 - 将资源分配到 AssetReference 字段(拖动到组件上)
- 将资源拖拽到 Group 窗口中
- 将资源放入标记为可寻址的文件夹中
管理可寻址资源
要管理可寻址资源,需要用到分组。默认情况下,可寻址资源会被添加到一个默认组中。也可以在 Groups
窗口中通过 New
> Packed Asset
来创建新的分组。
将资源添加到分组
将资源添加到分组有以下几种方式:
- 将资源从 Project 窗口拖到 Groups 窗口中的目标分组中
- 将资源从一个分组拖到另一个分组中
- 在资源的 Inspector 面板中激活
Addressable
选项,然后选择 Group - 将包含资源的文件夹拖到 Groups 窗口中的目标分组中,该文件夹中的所有资源都会被添加到该分组中
从分组中移除资源
在分组窗口选择一或多个资源,右键选择 Remove Addressables
,即可将资源从分组中移除。
添加或删除标签
除了分组外,每个可寻址资源还可以选择标签,标签主要有以下作用:
- 加载相同标签的多个资源
- 允许将相同标签的资源打包到一个 AB 中
- 可以使用标签来筛选资源
在分组窗口选择一或多个资源,然后通过资源的 Labels 下拉框来管理标签。
可寻址资源打包策略
在构建时,系统会根据可寻址资源的分组策略来构建 AB。该选项位于分组 Inspector 面板的 Bundle Mode 选项。有以下三种策略:
- Pack Together:将该组所有资源打包到一个 AB 中
- Pack Separately:将改组的每个资源单独打包到一个 AB 中
- Pack Together By Label:将该组的所有资源按照标签打包到一个 AB 中
具体选择哪种策略,需要根据实际情况来决定。
使用可寻址资源
有三种方式使用可寻址资源:
- 使用 AssetReference
- 使用可寻址资源的地址
- 使用可寻址资源的标签
使用 AssetReference
在 MonoBehaviour 或者 ScriptableObject 脚本中声明 AssetReference 字段,然后将可寻址资源拖拽到该字段上。在运行时,可以通过 AssetReference 的 LoadAssetAsync
方法异步加载资源。
public class Example : MonoBehaviour
{
public AssetReference assetReference;
private void Start()
{
var handle = assetReference.LoadAssetAsync<GameObject>();
handle.Completed += OnLoadCompleted;
}
private void OnLoadCompleted(AsyncOperationHandle handle)
{
if (handle.Status != AsyncOperationStatus.Succeeded)
{
return;
}
Instantiate(assetReference.Asset, transform);
}
private void OnDestroy()
{
assetReference.ReleaseAsset();
}
}
使用可寻址资源的地址
在运行时,可以通过可寻址资源的地址加载资源。
public class Example : MonoBehaviour
{
public string address;
private AsyncOperationHandle<GameObject> handle;
private void Start()
{
handle = Addressables.LoadAssetAsync<GameObject>(address);
handle.Completed += OnLoadCompleted;
}
private void OnLoadCompleted(AsyncOperationHandle<GameObject> handle)
{
if (handle.Status != AsyncOperationStatus.Succeeded)
{
return;
}
Instantiate(handle.Result, transform);
}
private void OnDestroy()
{
Addressables.Release(handle);
}
}
使用可寻址资源的标签
在运行时,可以通过可寻址资源的标签加载一组资源。
public class Example : MonoBehaviour
{
public List<string> labels;
private AsyncOperationHandle<IList<GameObject>> handle;
private void Start()
{
handle = Addressables.LoadAssetsAsync<GameObject>(labels, OnLoadCompleted);
}
private void OnLoadCompleted(GameObject obj)
{
Instantiate(obj, transform);
}
private void OnDestroy()
{
Addressables.Release(handle);
}
}
构建 AB 包
要打 AB 包,在 Groups
窗口中选择 Build
开始构建。有以下几种构建方式:
- Default Build Script:根据分组和其他设置执行一次完整构建
- Update Catalog:执行差异化构建,只构建发生变化的资源
- Play Mode Script:在 Play 模式下进行构建,主要用于测试
通过 Build
> Clean Build
可以清理已构建的 AB 包。
转换已有项目
针对尚未使用 Addressables 的已有项目,根据不同的资源,需要进行不同的转换步骤。
场景
按以下步骤将场景转换为可寻址:
- 将场景从
Scene In Build
中移除 - 在场景的 Inspector 面板上勾选 Addressable,或者将场景拖拽到 Group 窗口中
- 将加载场景的代码替换为 Addressables 的特有 API
预制体
- 在预制体的 Inspector 面板上勾选 Addressable,或者将预制体拖拽到 Group 窗口中
- 将加载预制体的代码替换为 Addressables 的特有 API
如果预制体仅在单个场景中使用,并且不需要运行时加载,则没有必要将其转换为可寻址。Addressable 会自动添加场景中的预制体,使其成为 AB 包的一部分。
资源文件
- 在资源文件的 Inspector 面板上勾选 Addressable,或者将资源文件拖拽到 Group 窗口中
- 将加载资源文件的代码替换为 Addressables 的特有 API
- 在不需要使用资源文件时,使用 Addressables 的 API 进行卸载
其他内容
上述内容只是 Addressables 的一些基本使用方法,更多内容可以参考官方文档。