U4S4L6——动态加载多个资源

本章代码关键字

1
2
Addressables.LoadAssetsAsync<>()    //根据资源名或标签名加载多个对象,也可以根据多种信息加载对象
Addressables.MergeMode //利用多种信息加载多个资源时,不同信息映射的不同资源组时,合并加载模式的枚举

根据资源名或标签名加载多个同名对象

  1. 可以根据 资源名或标签名+资源类型 来加载所有满足条件的对象
  2. 可以根据 资源名+标签名+资源类型+合并模式 来加载指定的单个或者多个对象,详见:Addressables.MergeMode

注意:我们还是可以通过泛型类型,来筛选资源类型

假设要加载这些同名资源:

image

  • 参数一:资源名或标签名
  • 参数二:加载结束后的回调函数,每加载出来一个就执行一次的回调函数
  • 参数三:如果为true​表示当资源加载失败时,会自动将已加载的资源和依赖都释放掉;如果为false​,需要自己手动来管理释放
1
2
3
4
5
6
7
void Start()
{
Addressables.LoadAssetsAsync<GameObject>("Cube", (obj) =>
{
print(obj.name);
}, true);
}

输出:image

可见,两个预设体被加载了出来,但是贴图未加载出来

如果要不限类型的将所有的同名资源加载出来,就需要泛型参数就需要Object

1
2
3
4
5
6
7
void Start()
{
Addressables.LoadAssetsAsync<Object>("Cube", (obj) =>
{
print(obj.name);
}, true);
}

输出:image

不仅可以通过在LoadAssetsAsync​传入回调函数来获取资源,
还可以向返回的AsyncOperationHandle<IList<>>​的Completed​属性添加回调函数

LoadAssetsAsync​内传入的加载完一个资源就执行的回调函数不同,
AsyncOperationHandle<IList<>>​的Completed​属性添加的回调函数会在加载完所有资源后才会执行
因此如果获取各个资源,需要遍历asyncOperationHandle<IList<>>.Result

1
2
3
4
5
6
7
8
9
10
11
12
void Start()
{
AsyncOperationHandle<IList<Object>> handle = Addressables.LoadAssetsAsync<Object>("Cube", null, true);

handle.Completed += (obj) =>
{
foreach (var item in obj.Result)
{
print(item.name);
}
};
}

输出:image

如果要进行资源释放管理 那么选择向AsyncOperationHandle<IList<>>​添加回调函数并获取资源,要方便一些
因为我们得到了返回值对象AsyncOperationHandle<IList<>>​,就可以释放资源了

1
2
3
4
5
6
7
8
9
AsyncOperationHandle<IList<Object>> handle = Addressables.LoadAssetsAsync<Object>("Cube", null, true);
handle.Completed += (obj) =>
{
foreach (var item in obj.Result)
{
print(item.name);
}
Addressables.Release(obj); //这里就可以释放资源
};

根据多种信息加载对象

同样还是使用 Addressables.LoadAssetsAsync<>()​

  • 参数一:想要加载资源的条件列表(资源名、Label名)

  • 参数二:每个加载资源结束后会调用的函数,会把加载到的资源传入该函数中

  • 参数三:可寻址的合并模式 Addressables.MergeMode​,用于合并请求结果的选项。

    如果键(A,B)​映射到不同结果(资源组)(A: [资源1, 资源2, 资源3], B: [资源1, 资源3, 资源4])
    这里传入的Addressables.MergeMode​合并模式枚举将决定如何返回这些资源

    • None​:不发生合并,将使用第一组结果 即加载返回[资源1, 资源2, 资源3]
    • UseFirst​:应用第一组结果,即加载返回[资源1, 资源2, 资源3]
    • Union​:合并所有结果,即加载返回[资源1, 资源2, 资源3, 资源4]
    • Intersection​:使用相交结果,即加载返回[资源1, 资源3]
  • 参数四:如果为true​表示当资源加载失败时,会自动将已加载的资源和依赖都释放掉,如果为false​,需要自己手动来管理释放(可选)

假设要加载:

image

(Cube,Red)​映射到不同结果(资源组)(Cube: [资源1, 资源2, 资源3], Red: [资源1, 资源3, 资源4])

演示各种模式下加载的结果:

  • None​:不发生合并,将使用第一组结果 即加载返回[资源1, 资源2, 资源3]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Start()
    {
    List<string> strs = new List<string>() { "Cube", "Red" };
    print("合并模式为:None");
    Addressables.LoadAssetsAsync<Object>(strs, (obj) =>
    {
    print(obj.name);
    }, Addressables.MergeMode.None);
    }

    输出:image

  • UseFirst​:应用第一组结果,即加载返回[资源1, 资源2, 资源3]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Start()
    {
    List<string> strs = new List<string>() { "Cube", "Red" };
    print("合并模式为:UseFirst");
    Addressables.LoadAssetsAsync<Object>(strs, (obj) =>
    {
    print(obj.name);
    }, Addressables.MergeMode.UseFirst);
    }

    输出:image

  • Union​:合并所有结果,即加载返回[资源1, 资源2, 资源3, 资源4]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Start()
    {
    List<string> strs = new List<string>() { "Cube", "Red" };
    print("合并模式为:Union");
    Addressables.LoadAssetsAsync<Object>(strs, (obj) =>
    {
    print(obj.name);
    }, Addressables.MergeMode.Union);
    }

    输出:image

  • Intersection​:使用相交结果,即加载返回[资源1, 资源3]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Start()
    {
    List<string> strs = new List<string>() { "Cube", "Red" };
    print("合并模式为:Intersection");
    Addressables.LoadAssetsAsync<Object>(strs, (obj) =>
    {
    print(obj.name);
    }, Addressables.MergeMode.Intersection);
    }

    输出:image