基础使用

本章节介绍 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 常见错误与解决方法

  1. 资源没有卸载
    → 检查 refCount 是否为 0。

  2. 多次加载同一资源
    → ResLoad 会自动缓存,不会产生多副本。

  3. 进度始终为 0
    → ResourcesProvider 不支持真实进度。


9. 小结

在 ResLoad 中:

  • ResManager 是统一入口
  • Provider 决定资源来源
  • ResInfo 负责缓存与状态
  • 引用计数保证资源安全卸载
  • 三种异步方式适配不同使用场景
  • 批量加载适用于场景与大型 UI 初始化

通过这些机制,ResLoad 实现了一个稳定、可扩展、统一的资源加载体系,可广泛用于各种项目结构中。