Unity Addressables 运行时加载附加 Catalog 使用详解

ko-fi

当项目需要在不重新发布应用的前提下,增量地引入新资源或从其他项目拉取内容时,运行时加载“附加 Catalog”是最干净、最稳的方式。

加载附加 Catalog

  • 加载附加 Catalog: 使用 Addressables.LoadContentCatalogAsync(path, autoReleaseHandle) 从本地文件或远程托管地址加载新的 Catalog;加载完成后,Catalog 中的键可直接用于 Addressables.LoadAssetAsync 等 API。

  • 操作句柄释放: 若想让远程 Catalog 被重新下载,之前对同一路径的 LoadContentCatalogAsync 必须释放;设置 autoReleaseHandle = true 可自动避免操作缓存导致的“拿到旧结果”问题。

  • 不可卸载: 已加载的 Catalog 不能“卸载”,但可以“更新”。更新前需释放对应加载操作句柄。

1
2
3
4
5
6
7
8
9
public IEnumerator Start()
{
// 加载一个 Catalog,并自动释放操作句柄。
AsyncOperationHandle<IResourceLocator> handle
= Addressables.LoadContentCatalogAsync("path_to_secondary_catalog", true);
yield return handle;

// ...
}

只检查远程 Catalog 是否有更新

只检查远程 Catalog 是否有更新,而不立即下载或更新,可以使用Addressables.CheckForCatalogUpdates()。这个方法会返回一个AsyncOperationHandle<List<string>>,其中包含需要更新的 Catalog 名称列表。你可以在完成回调里判断是否有更新,然后再决定是否调用 Addressables.UpdateCatalogs()

  • 只检查,不更新: 使用 CheckForCatalogUpdates() 就能只获取更新信息,而不会阻塞或下载新 Catalog。

  • 哈希文件机制: 如果远程目录下有 .hash 文件,Addressables 会根据哈希判断是否有新版本。

  • 更新时机: 如果只想提示用户有更新,可以在 UI 上显示提示;真正调用 UpdateCatalogs() 时再下载。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
IEnumerator CheckRemoteCatalogs()
{
// 创建一个列表来存储需要更新的 Catalog
List<string> catalogsToUpdate = new List<string>();

// 调用检查方法
AsyncOperationHandle<List<string>> checkHandle = Addressables.CheckForCatalogUpdates();

// 在 Completed 回调中获取结果
checkHandle.Completed += op =>
{
catalogsToUpdate.AddRange(op.Result);
};

// 等待操作完成
yield return checkHandle;

// 判断是否有需要更新的 Catalog
if (catalogsToUpdate.Count > 0)
{
Debug.Log("发现远程 Catalog 有更新: " + string.Join(",", catalogsToUpdate));
// 此时你可以选择是否调用 UpdateCatalogs 来真正更新
// yield return Addressables.UpdateCatalogs(catalogsToUpdate);
}
else
{
Debug.Log("远程 Catalog 没有更新");
}

// 释放操作句柄
checkHandle.Release();
}

更新远程 Catalog

更新远程 Catalog(而不是本地 Catalog),关键在于使用 Addressables.UpdateCatalogs() 并确保你传入的远程 Catalog 名称列表。

  • 只更新远程 Catalog:CheckForCatalogUpdates() 会返回所有需要更新的 Catalog 名称(包括远程和本地)。

如果你只想更新远程 Catalog,可以在结果列表里筛选出远程 Catalog 的名字(通常是加载时指定的 URL 或远程路径)。

  • 阻塞特性: UpdateCatalogs 会阻塞其他 Addressables 请求,直到更新完成。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
IEnumerator UpdateRemoteCatalogs(List<string> catalogsToUpdate)
{
// 调用 UpdateCatalogs 并传入需要更新的远程 Catalog 列表
AsyncOperationHandle<List<IResourceLocator>> updateHandle =
Addressables.UpdateCatalogs(catalogsToUpdate);

yield return updateHandle;

if (updateHandle.Status == AsyncOperationStatus.Succeeded)
{
Debug.Log("远程 Catalog 更新成功");
}
else
{
Debug.LogError("远程 Catalog 更新失败: " + updateHandle.OperationException);
}

updateHandle.Release();
}

参考文档

https://docs.unity3d.com/Packages/com.unity.addressables@1.22/manual/LoadContentCatalogAsync.html