Files
UnityAI/modules/frameworks/资源管理/使用指南.md
2026-07-10 17:50:20 +08:00

6.2 KiB
Raw Permalink Blame History

资源管理使用指南

一、加载资源

业务统一通过 HFFunCatalogue.Asset 调用:

HFFunCatalogue.Asset.LoadAsset(@"Perfabs\Tower\LavaGuard.prefab", (response, args) =>
{
    GameObject prefab = response.GetAsset<GameObject>();
    if (prefab == null)
    {
        SFP.Error("Load LavaGuard failed.");
        return;
    }

    GameObject instance = GameObject.Instantiate(prefab);
});

资源路径仍按项目 HFAssetBundlePathAttribute、语言目录和 AssetBundle 配置解析。业务不要直接创建 HFAssetLoader 或依赖 assetBundleKey。

二、主动卸载

业务使用易读名称接口:

bool prefabUnloaded = HFFunCatalogue.Asset.UnloadPrefabObject("LavaGuard");
bool assetUnloaded = HFFunCatalogue.Asset.UnloadAssetObject("common_icon");

调用前必须确认业务实例和窗口已经释放引用。框架会查找唯一 loader并检查加载、请求和释放状态未找到、重名或仍不可卸载时返回 false

AssetBundle.Unload(false) 不会自动销毁已经实例化的 GameObject。业务仍应先关闭窗口或 Destroy 实例,再请求卸载 Bundle 内存。

同名资源存在多个 loader 时不要随机卸载;使用更完整的资源路径,或根据错误日志定位冲突来源。

三、内存查看

long bytes = HFFunCatalogue.Asset.GetLoadedAssetBundleMemorySize();
float kb = HFFunCatalogue.Asset.GetLoadedAssetBundleMemorySizeKB();
float mb = HFFunCatalogue.Asset.GetLoadedAssetBundleMemorySizeMB();
string text = HFFunCatalogue.Asset.GetLoadedAssetBundleMemorySizeText();
HFFunCatalogue.Asset.LogLoadedAssetBundleMemorySize();

该数值是已完成 loader 的 AssetBundle 内存估算。LoadFromFileAsync 没有托管 byte[] 时使用文件长度估算,因此只用于调试面板和趋势观察。

四、AssetBundle CDN 保存路径

平台层可以在初始化时配置:

HFFunCatalogue.Asset.SetCdnSaveRootPath(platformSaveRoot);

未配置或传入无效值时使用 PersistentData 资源根目录。平台专用目录由平台适配层传入,不在通用 ESF 逻辑中硬编码。

五、分包 V2 配置

非热更启动层使用:

SFSubPackageRuntimeV2.Instance.SetDownloadConfig(
    downloadSetting.WebBaseUrlBase,
    downloadSetting.AppVersion,
    downloadSetting.AppPartner);

如平台使用自定义文件系统,调用 SetLocalStorage 重载传入 exists、read、write 和 delete 回调。默认存储根目录为 PersistentData。

SetDownLoadUri(string) 只作为单地址兼容入口,新代码优先使用 SetDownloadConfig

六、启动代码更新

GameDllManager 负责调用:

SFSubPackageRuntimeV2.Instance.CheckAndDownloadBootstrapFiles(
    OnProgress,
    OnBootstrapCompleted,
    OnManifestFailed);

成功下载不等于启动完成。AOT、HotUpdate 和热更入口成功后,调用:

SFSubPackageRuntimeV2.Instance.CommitBootstrapCodeLoaded(OnCommitted);

提交成功后普通资源 API 才可使用。失败时调用 InvalidateBootstrapCode 保持门禁关闭,并向业务展示重试或退出。

七、更新普通资源

更新基础、BuiltIn 和历史包

HFSubPackageManager.Instance.CheckAndDownloadAllFiles(
    progress => UpdateLoading(progress),
    () => OnResourceUpdateCompleted(),
    result => SFP.Error(SFDownloadResultLog.Format("普通资源下载失败", result)));

该接口会先完成差异扫描并回调差异结果再开始删除旧遮挡文件和下载。它只处理基础文件、BuiltIn 包、历史已下载包及依赖闭包。

按枚举下载 Package

HFSubPackageManager.Instance.CheckAndDownloadPackage(
    enHFSubPackageId.PACKAGE_1001,
    progress => UpdateLoading(progress),
    () => OnPackageReady(),
    result => SFP.Error(SFDownloadResultLog.Format("Package 下载失败", result)));

枚举由编辑器生成,成员注释来自 Package DisplayName。不要手改 Generated/enHFSubPackageId.cs

字符串接口仍保留:

HFSubPackageManager.Instance.CheckAndDownloadPackage(
    packageId, progress, finish, failed);

查询 Package 状态

bool ready = HFSubPackageManager.Instance.IsPackageDownloaded(
    enHFSubPackageId.PACKAGE_1001);

返回 true 需要Bootstrap 已提交、Package 存在于当前清单和 DownloadedPackageIds、依赖包已记录、全部文件状态符合当前 MD5。BuiltIn = true 本身不等于业务已经下载过。

按文件兜底

资源加载知道目标 AB 路径时可以使用 CheckAndDownloadFile。运行时会从 Files[] 找到目标文件,递归展开 Dependencies下载差异后重试原加载流程。

八、进度和失败

进度对象包含:

  • StageMaxDownloadedCount
  • TotalBytesDownloadedBytes
  • CurrentPathCurrentFileSize
  • CurrentFileDownloadedBytesCurrentFileProgressProgress

失败结果包含:

  • DifferenceFilesDeletedOldFilesUpdatedFiles
  • FailedFiles[].Path
  • ExpectedMD5ErrorTriedUrls

单文件只有写入完成且 MD5 通过后才增加完成计数。进程被结束后,下次启动会重新读取远端清单和本地状态,逐文件检查;已完成文件复用,未完成文件从文件头重新下载,不做单文件字节级续传。

九、验证清单

  • PersistentData 文件正确时不访问 CDN。
  • PersistentData 错误但 StreamingAssets 正确时使用母包文件并处理遮挡旧文件。
  • 两处均无有效文件时从 CDN 下载到默认或外部保存路径。
  • 差异日志在普通资源下载进度之前输出。
  • 两个 Package 共享依赖时只建立一个 Path + MD5 任务。
  • 远端 MD5 变化后历史 Package 会参与 CheckAndDownloadAllFiles
  • 下载失败释放进行中任务,下一次请求可以重试。
  • Android/WebGL 的 StreamingAssets 失败会继续 fallback不会阻塞主线程。

文档关联

文档 关联原因
资源管理入口 架构、来源顺序和 V2 数据流
UI 窗口系统 UI 加载与卸载调用方
Hotfix 启动 Bootstrap 接入
开发规则 业务入口和异步规则