U4S4L14——根据资源定位信息加载资源

本章代码关键字

1
2
IResourceLocation                                //资源定位信息接口,可通过它获取资源的主键,内部ID,以及资源类型等等消息
Addressables.LoadResourceLocationsAsync() //通过资源名或者标签名或者资源名标签名组合加载符合条件的资源定位信息

回顾学过的加载可寻址资源的方式

  1. 通过标识类进行加载(指定资源加载)

  2. 通过资源名或标签名加载单个资源(动态加载)

    1
    Addressables.LoadAssetAsync<GameObject>("Cube")
  3. 通过资源名或标签名或两者组合加载多个资源(动态加载)

    1
    2
    3
    4
    5
    Addressables.LoadAssetsAsync<GameObject>(
    new List<string>() { "Cube", "SD" },
    (obj) => { /* 使用资源的逻辑 */ },
    Addressables.MergeMode.Intersection
    );

加载资源时Addressables帮助我们做了哪些事情

  1. 查找指定键的资源位置
  2. 收集依赖项列表
  3. 下载所需的所有远程AB包
  4. 将AB包加载到内存中
  5. 设置 Result​ 资源对象的值
  6. 更新 Status​ 状态变量参数并且调用完成事件 Completed

如果加载成功Status​状态为成功,并且可以从Result​中得到内容

如果加载失败除了 Status​ 状态为失败外
如果我们启用了 Log Runtime Exceptions 选项 会在 Console 窗口打印信息

image

根据名字或者标签获取 资源定位信息 加载资源

诸如Addressables.LoadAssetAsync()​和Addressables.LoadAssetsAsync()​都有IResourcesLocation​的参数的重载
因此我们可以通过Addressables.LoadResourceLocationsAsync()​来获取IResourcesLocation​资源定位信息

  • 参数一:资源名或者标签名
  • 参数二:资源类型
  • 返回值:AsyncOperationHandle<IList<IResourceLocation>>​,加载资源加载信息列表的处理类

要获取资源加载信息,需要向返回的AsyncOperationHandle​的Completed​属性添加回调函数,和直接加载资源的步骤类似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Start()
{
AsyncOperationHandle<IList<IResourceLocation>> handle = Addressables.LoadResourceLocationsAsync("Cube", typeof(GameObject));
handle.Completed += (obj) =>
{
if (obj.Status == AsyncOperationStatus.Succeeded)
{
foreach (var item in obj.Result)
{
//我们可以通过定位消息,再去加载资源
print(item.PrimaryKey);
Addressables.LoadAssetAsync<GameObject>(item).Completed += (obj) =>
{
Instantiate(obj.Result);
};
}
}
else
{
Addressables.Release(handle);
}
};
}

输出:image

这样就是两步加载,先加载了资源定位信息,然后根据资源定位信息加载资源
而原本的直接通过资源名或者标签名加载资源的方法就是将加载资源定位信息封装到了方法内部

根据名字标签组合信息获取 资源定位信息 加载资源

我们同样可以通过资源名和标签名的组合的列表来加载特定的多个资源

  • 参数一:资源名和标签名的组合
  • 参数二:合并模式
  • 参数三:资源类型
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
void Start()
{
AsyncOperationHandle<IList<IResourceLocation>> handle1 = Addressables.LoadResourceLocationsAsync(
new List<string>() { "Cube", "Sphere", "SD" },
Addressables.MergeMode.Union,
typeof(Object));

handle1.Completed += (obj) =>
{
if (obj.Status == AsyncOperationStatus.Succeeded)
{
foreach (var item in obj.Result)
{
//我们可以通过定位消息,再去加载资源
print(item.PrimaryKey);
Addressables.LoadAssetAsync<Object>(item).Completed += (obj) =>
{
//处理资源
};
}
}
else
{
Addressables.Release(handle);
}
};
}

输出:image

根据资源定位信息加载资源的注意事项

  1. 资源信息当中提供了一些额外信息

    • PrimaryKey​:资源主键(资源名)
    • InternalId​:资源内部ID(资源路径)
    • ResourceType​:资源类型(Type​可以获取资源类型名)

    我们可以利用这些信息处理一些特殊需求,比如加载多个不同类型资源时 可以通过他们进行判断再分别进行处理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    AsyncOperationHandle<IList<IResourceLocation>> handle1 = Addressables.LoadResourceLocationsAsync(
    new List<string>() { "Cube", "Sphere", "SD" },
    Addressables.MergeMode.Union,
    typeof(Object));
    handle1.Completed += (obj) =>
    {
    if (obj.Status == AsyncOperationStatus.Succeeded)
    {
    foreach (var item in obj.Result)
    {
    //我们可以通过定位消息,再去加载资源
    print($"key: {item.PrimaryKey}, id: {item.InternalId}, type: {item.ResourceType.Name}");
    Addressables.LoadAssetAsync<Object>(item).Completed += (obj) =>
    {
    //处理资源
    };
    }
    }
    else
    {
    Addressables.Release(handle);
    }
    };

    输出:image

  2. 根据资源定位信息加载资源并不会加大我们加载开销,只是分步完成加载了而已