基础使用
本章节介绍 ResLoad 在实际项目中的使用方式,包括同步与异步加载、批量加载、引用计数、卸载策略与调试方法。
所有示例均基于 ResManager 提供的统一 API。
1. 路径与资源键值
ResLoad 使用以下规则确定资源的唯一标识:fullPath + "_" + typeof(T).Name
示例:
res://UI/LoginPanel_GameObject
file://C:/Data/Icon.png_Texture2D
这样可以确保:
- 同路径不同类型资源不冲突
- 同步与异步共享缓存
- Provider 之间切换不影响缓存机制
Provider 前缀说明:
| 前缀 | 加载方式 |
|---|---|
res:// | ResourcesProvider |
file:// | FileProvider |
http(s):// | WebProvider |
editor:// | EditorProvider(仅编辑器) |
| (无前缀) | 默认为 Resources |
2. 同步加载(Load)
同步加载适用于体量小、加载快、不需要进度条的资源,例如 UI Prefab、图标、小音效等。
示例:
var prefab = ResManager.Instance.Load<GameObject>("res://UI/LoginPanel");
同步加载行为:
1.缓存未命中 → 首次加载
- 调用 Provider.Load
- 创建 ResInfo,并记录 asset
- 引用计数 +1
2.缓存命中(已加载完成)
- 直接返回 asset
- 引用计数 +1
3.资源正在异步加载
- 终止异步等待
- Provider 同步重新加载(托底机制)
- 引用计数保持正确
同步调用总能返回资源本体(或 null),确保逻辑稳定。
3. 异步加载(LoadAsync)
ResLoad 提供 三种异步方式,满足不同使用场景。
3.1 async/await(推荐方式)
var clip = await ResManager.Instance.LoadAsync<AudioClip>("res://Audio/BGM_Main");
行为:
- 若首次加载 → 创建 ResInfo + 启动 Provider 异步加载
- 若缓存命中 → 直接返回 asset
- 若资源正在加载中 → 挂起等待现有任务(不重复发起)
3.2 回调形式
ResManager.Instance.LoadAsyncCallback<GameObject>("res://UI/Item", obj =>
{
Debug.Log("加载完成");
});
内部仍使用 await 加载,回调仅作为通知方式。
3.3 句柄形式(支持进度条)
var op = ResManager.Instance.LoadAsyncHandle<Texture2D>("http://server.com/bg.png");
op.Completed += handle =>
{
Debug.Log("加载完成,资源:" + handle.Result);
};
可通过:op.Progress实时获取加载进度。
适用于:
- 需要进度条 如:场景 Loading UI
- 大型资源加载
- 无法使用 async/await 的流程控制
4. 批量异步加载(BatchLoadAsync)
用于加载多个资源并显示整体进度,典型用于:
- 场景切换预加载
- 大 UI 面板初始化
- 大地图或章节加载
示例
var list = new List<string>
{
"res://UI/LoginPanel",
"res://Audio/BGM_Main",
"http://server.com/icon.png"
};
var op = ResManager.Instance.BatchLoadAsync(list);
op.Completed += o =>
{
Debug.Log("全部加载完成");
};
行为说明:
- 顺序加载每个资源(避免过多并发)
- 资源的加载结果存在 op.Results 中
- op.Progress 表示整体进度(0~1)
5. 引用计数(RefCount)
ResLoad 使用引用计数确保资源安全卸载:
| 操作 | 行为 |
|---|---|
| Load / LoadAsync | 引用计数 +1 |
| UnloadAsset | 引用计数 -1 |
| refCount == 0 且 isDel == true | 立即卸载 |
| refCount == 0 且 isDel == false | 等待 Clear / UnloadUnusedAssets |
获取引用计数
int count = ResManager.Instance.GetRefCount<GameObject>("res://UI/LoginPanel");
常见问题
- 引用计数为负数:说明加载与卸载次数不对等
- 资源未卸载:refCount > 0 或 isDel 未标记
6. 卸载资源(UnloadAsset)
卸载一个资源的引用,并根据情况执行卸载。
基础用法
ResManager.Instance.UnloadAsset<GameObject>("res://UI/LoginPanel");
若 refCount == 0 && isDel == true,则立刻执行卸载。
立即卸载资源
ResManager.Instance.UnloadAsset<GameObject>("res://UI/LoginPanel", isDel: true);
异步加载中的卸载行为 若资源仍在加载中:
- 不立即卸载
- 加载完成后由系统自动判断是否需要卸载
- 不会造成异常或空引用
7. 清空缓存与卸载未使用资源
7.1 清理未使用资源(引用为零)
await ResManager.Instance.UnloadUnusedAssets();
流程:
- 移除所有 refCount == 0 && isDel == true 的资源
- 调用 Unity 内部的 Resources.UnloadUnusedAssets
7.2 强制清空整个缓存字典
异步清空
await ResManager.Instance.ClearDicAsync();
同步清空
ResManager.Instance.ClearDic();
清空内容包括:
- ResManager 缓存字典
- 所有 Provider 的内部缓存
- Unity 未引用资源(若使用异步版本)
典型使用场景:
- 场景切换
- 大型资源重加载
- 内存清理点
8. 调试与最佳实践
8.1 建议的资源管理方式
| 资源类型 | 建议方式 |
|---|---|
| UI Prefab | 同步加载 |
| 图标 / 小图 | 同步加载 |
| 大音频 | 异步加载 |
| 大贴图 / 模型 | 异步句柄(带进度) |
| 网络资源 | 使用 http(s) Provider |
| 编辑器资源 | 使用 editor:// |
8.2 常见错误与解决方法
-
资源没有卸载
→ 检查 refCount 是否为 0。 -
多次加载同一资源
→ ResLoad 会自动缓存,不会产生多副本。 -
进度始终为 0
→ ResourcesProvider 不支持真实进度。
9. 小结
在 ResLoad 中:
- ResManager 是统一入口
- Provider 决定资源来源
- ResInfo 负责缓存与状态
- 引用计数保证资源安全卸载
- 三种异步方式适配不同使用场景
- 批量加载适用于场景与大型 UI 初始化
通过这些机制,ResLoad 实现了一个稳定、可扩展、统一的资源加载体系,可广泛用于各种项目结构中。