【整合】 框架使用规则
This commit is contained in:
@@ -1,102 +1,174 @@
|
||||
# 资源管理使用指南
|
||||
|
||||
## 一、AssetBundle 资源加载
|
||||
## 一、加载资源
|
||||
|
||||
### 1.1 加载资源示例
|
||||
业务统一通过 `HFFunCatalogue.Asset` 调用:
|
||||
|
||||
```csharp
|
||||
public class ResourceLoader : MonoBehaviour
|
||||
HFFunCatalogue.Asset.LoadAsset(@"Perfabs\Tower\LavaGuard.prefab", (response, args) =>
|
||||
{
|
||||
public void LoadPlayerModel(int resId, Action<GameObject> onLoaded)
|
||||
GameObject prefab = response.GetAsset<GameObject>();
|
||||
if (prefab == null)
|
||||
{
|
||||
// 通过 HFFunCatalogue 统一入口加载资源
|
||||
// resId: 从 Res 配置表中读取的资源 ID
|
||||
HFFunCatalogue.Asset.LoadAsset(resId, (res, obj) =>
|
||||
{
|
||||
if (obj != null)
|
||||
{
|
||||
GameObject model = res.GetAsset<GameObject>();
|
||||
onLoaded?.Invoke(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"加载失败: resId={resId}");
|
||||
}
|
||||
});
|
||||
SFP.Error("Load LavaGuard failed.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 1.2 实体资源加载示例
|
||||
|
||||
```csharp
|
||||
// 在 Entity 中加载资源
|
||||
HFFunCatalogue.Asset.LoadAsset(data.EntityRes.Id, (res, obj) => {
|
||||
if (!entity.isDeath)
|
||||
{
|
||||
var Boddy = res.GetAsset<GameObject>();
|
||||
data.SetBoddy(Boddy);
|
||||
}
|
||||
GameObject instance = GameObject.Instantiate(prefab);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
资源路径仍按项目 `HFAssetBundlePathAttribute`、语言目录和 AssetBundle 配置解析。业务不要直接创建 `HFAssetLoader` 或依赖 assetBundleKey。
|
||||
|
||||
## 二、资源管理 API
|
||||
## 二、主动卸载
|
||||
|
||||
### 2.1 常用方法
|
||||
业务使用易读名称接口:
|
||||
|
||||
| 类别 | 管理器 | 常用方法 |
|
||||
|-----|-------|---------|
|
||||
| **资源** | `HFABMgr` | `LoadAsset()`, `OnStartLoad()` |
|
||||
|
||||
### 2.2 资源加载流程
|
||||
|
||||
```
|
||||
资源加载流程:
|
||||
OnStartLoad(request)
|
||||
│
|
||||
▼
|
||||
检查缓存 → 获取/创建 HFAssetLoader
|
||||
│
|
||||
▼
|
||||
loader.AddRequest(request)
|
||||
│
|
||||
▼
|
||||
loader.LoadAsset() → 异步加载
|
||||
│
|
||||
▼
|
||||
加载完成 → 回调处理
|
||||
```csharp
|
||||
bool prefabUnloaded = HFFunCatalogue.Asset.UnloadPrefabObject("LavaGuard");
|
||||
bool assetUnloaded = HFFunCatalogue.Asset.UnloadAssetObject("common_icon");
|
||||
```
|
||||
|
||||
---
|
||||
调用前必须确认业务实例和窗口已经释放引用。框架会查找唯一 loader,并检查加载、请求和释放状态;未找到、重名或仍不可卸载时返回 `false`。
|
||||
|
||||
## 三、资源管理注意事项
|
||||
`AssetBundle.Unload(false)` 不会自动销毁已经实例化的 GameObject。业务仍应先关闭窗口或 Destroy 实例,再请求卸载 Bundle 内存。
|
||||
|
||||
### 3.1 性能优化建议
|
||||
同名资源存在多个 loader 时不要随机卸载;使用更完整的资源路径,或根据错误日志定位冲突来源。
|
||||
|
||||
- 及时释放不再使用的资源
|
||||
- 使用异步加载避免卡顿
|
||||
- 合理使用资源缓存
|
||||
## 三、内存查看
|
||||
|
||||
---
|
||||
```csharp
|
||||
long bytes = HFFunCatalogue.Asset.GetLoadedAssetBundleMemorySize();
|
||||
float kb = HFFunCatalogue.Asset.GetLoadedAssetBundleMemorySizeKB();
|
||||
float mb = HFFunCatalogue.Asset.GetLoadedAssetBundleMemorySizeMB();
|
||||
string text = HFFunCatalogue.Asset.GetLoadedAssetBundleMemorySizeText();
|
||||
HFFunCatalogue.Asset.LogLoadedAssetBundleMemorySize();
|
||||
```
|
||||
|
||||
**版本**: v1.0
|
||||
**生效日期**: 2026年
|
||||
**适用范围**: GiftGameX 项目业务开发人员
|
||||
该数值是已完成 loader 的 AssetBundle 内存估算。`LoadFromFileAsync` 没有托管 byte[] 时使用文件长度估算,因此只用于调试面板和趋势观察。
|
||||
|
||||
---
|
||||
## 四、AssetBundle CDN 保存路径
|
||||
|
||||
平台层可以在初始化时配置:
|
||||
|
||||
```csharp
|
||||
HFFunCatalogue.Asset.SetCdnSaveRootPath(platformSaveRoot);
|
||||
```
|
||||
|
||||
未配置或传入无效值时使用 PersistentData 资源根目录。平台专用目录由平台适配层传入,不在通用 ESF 逻辑中硬编码。
|
||||
|
||||
## 五、分包 V2 配置
|
||||
|
||||
非热更启动层使用:
|
||||
|
||||
```csharp
|
||||
SFSubPackageRuntimeV2.Instance.SetDownloadConfig(
|
||||
downloadSetting.WebBaseUrlBase,
|
||||
downloadSetting.AppVersion,
|
||||
downloadSetting.AppPartner);
|
||||
```
|
||||
|
||||
如平台使用自定义文件系统,调用 `SetLocalStorage` 重载传入 exists、read、write 和 delete 回调。默认存储根目录为 PersistentData。
|
||||
|
||||
旧 `SetDownLoadUri(string)` 只作为单地址兼容入口,新代码优先使用 `SetDownloadConfig`。
|
||||
|
||||
## 六、启动代码更新
|
||||
|
||||
`GameDllManager` 负责调用:
|
||||
|
||||
```csharp
|
||||
SFSubPackageRuntimeV2.Instance.CheckAndDownloadBootstrapFiles(
|
||||
OnProgress,
|
||||
OnBootstrapCompleted,
|
||||
OnManifestFailed);
|
||||
```
|
||||
|
||||
成功下载不等于启动完成。AOT、HotUpdate 和热更入口成功后,调用:
|
||||
|
||||
```csharp
|
||||
SFSubPackageRuntimeV2.Instance.CommitBootstrapCodeLoaded(OnCommitted);
|
||||
```
|
||||
|
||||
提交成功后普通资源 API 才可使用。失败时调用 `InvalidateBootstrapCode` 保持门禁关闭,并向业务展示重试或退出。
|
||||
|
||||
## 七、更新普通资源
|
||||
|
||||
### 更新基础、BuiltIn 和历史包
|
||||
|
||||
```csharp
|
||||
HFSubPackageManager.Instance.CheckAndDownloadAllFiles(
|
||||
progress => UpdateLoading(progress),
|
||||
() => OnResourceUpdateCompleted(),
|
||||
result => SFP.Error(SFDownloadResultLog.Format("普通资源下载失败", result)));
|
||||
```
|
||||
|
||||
该接口会先完成差异扫描并回调差异结果,再开始删除旧遮挡文件和下载。它只处理基础文件、BuiltIn 包、历史已下载包及依赖闭包。
|
||||
|
||||
### 按枚举下载 Package
|
||||
|
||||
```csharp
|
||||
HFSubPackageManager.Instance.CheckAndDownloadPackage(
|
||||
enHFSubPackageId.PACKAGE_1001,
|
||||
progress => UpdateLoading(progress),
|
||||
() => OnPackageReady(),
|
||||
result => SFP.Error(SFDownloadResultLog.Format("Package 下载失败", result)));
|
||||
```
|
||||
|
||||
枚举由编辑器生成,成员注释来自 Package DisplayName。不要手改 `Generated/enHFSubPackageId.cs`。
|
||||
|
||||
字符串接口仍保留:
|
||||
|
||||
```csharp
|
||||
HFSubPackageManager.Instance.CheckAndDownloadPackage(
|
||||
packageId, progress, finish, failed);
|
||||
```
|
||||
|
||||
### 查询 Package 状态
|
||||
|
||||
```csharp
|
||||
bool ready = HFSubPackageManager.Instance.IsPackageDownloaded(
|
||||
enHFSubPackageId.PACKAGE_1001);
|
||||
```
|
||||
|
||||
返回 `true` 需要:Bootstrap 已提交、Package 存在于当前清单和 `DownloadedPackageIds`、依赖包已记录、全部文件状态符合当前 MD5。`BuiltIn = true` 本身不等于业务已经下载过。
|
||||
|
||||
### 按文件兜底
|
||||
|
||||
资源加载知道目标 AB 路径时可以使用 `CheckAndDownloadFile`。运行时会从 `Files[]` 找到目标文件,递归展开 Dependencies,下载差异后重试原加载流程。
|
||||
|
||||
## 八、进度和失败
|
||||
|
||||
进度对象包含:
|
||||
|
||||
- `Stage`、`Max`、`DownloadedCount`
|
||||
- `TotalBytes`、`DownloadedBytes`
|
||||
- `CurrentPath`、`CurrentFileSize`
|
||||
- `CurrentFileDownloadedBytes`、`CurrentFileProgress`、`Progress`
|
||||
|
||||
失败结果包含:
|
||||
|
||||
- `DifferenceFiles`、`DeletedOldFiles`、`UpdatedFiles`
|
||||
- `FailedFiles[].Path`
|
||||
- `ExpectedMD5`、`Error`、`TriedUrls`
|
||||
|
||||
单文件只有写入完成且 MD5 通过后才增加完成计数。进程被结束后,下次启动会重新读取远端清单和本地状态,逐文件检查;已完成文件复用,未完成文件从文件头重新下载,不做单文件字节级续传。
|
||||
|
||||
## 九、验证清单
|
||||
|
||||
- PersistentData 文件正确时不访问 CDN。
|
||||
- PersistentData 错误但 StreamingAssets 正确时使用母包文件并处理遮挡旧文件。
|
||||
- 两处均无有效文件时从 CDN 下载到默认或外部保存路径。
|
||||
- 差异日志在普通资源下载进度之前输出。
|
||||
- 两个 Package 共享依赖时只建立一个 `Path + MD5` 任务。
|
||||
- 远端 MD5 变化后历史 Package 会参与 `CheckAndDownloadAllFiles`。
|
||||
- 下载失败释放进行中任务,下一次请求可以重试。
|
||||
- Android/WebGL 的 StreamingAssets 失败会继续 fallback,不会阻塞主线程。
|
||||
|
||||
## 文档关联
|
||||
|
||||
> 当本文档发生变更时,应同步检查以下关联文档,避免信息不一致。
|
||||
|
||||
| 文档 | 关联原因 |
|
||||
|---|---|
|
||||
| [资源管理入口](README.md) | 本文件是资源管理模块的子文档 |
|
||||
| [UI 窗口系统](../UI窗口系统/README.md) | UI 资源加载依赖资源管理 |
|
||||
| [实体系统](../实体系统/README.md) | 实体资源加载依赖资源管理 |
|
||||
| [场景系统](../场景系统.md) | 场景资源加载依赖资源管理 |
|
||||
| [modules/模块索引.md](../../模块索引.md) | 模块索引是项目知识总入口 |
|
||||
| [rules/10-架构说明.md](../../../rules/10-架构说明.md) | 架构说明定义总体分层和依赖方向 |
|
||||
| [rules/30-模块登记规则.md](../../../rules/30-模块登记规则.md) | 模块登记规则定义分类和状态口径 |
|
||||
| [资源管理入口](README.md) | 架构、来源顺序和 V2 数据流 |
|
||||
| [UI 窗口系统](../UI窗口系统/README.md) | UI 加载与卸载调用方 |
|
||||
| [Hotfix 启动](../Hotfix启动.md) | Bootstrap 接入 |
|
||||
| [开发规则](../../../rules/20-开发规则.md) | 业务入口和异步规则 |
|
||||
|
||||
Reference in New Issue
Block a user