Notifications
Article
Addressable系统的加载资源API总结
Published 3 months ago
682
5
Addressable系统的加载资源API总结
你好,我是跟着大智学Unity的萌新,我叫小新,这是我本周的学习总结报告哦。
大智:“小新,这周学习有没有遇到什么问题呢?”
小新:“确实遇到了,那个`Addressables.LoadAssetsAsync`API,我有一次怎么都加载不出来资源,倒腾了半天,最后发现是参数传的不对。。。”
大智:“那你现在搞明白了没?”
小新:“基本搞明白了。。。”
大智:“那你把Addressable中的加载API总结一下吧~我看看你到底搞明白了没。”
小新:“好嘞。”

Addressable系统的加载资源API

Addressable中加载资源主要有两个途径:
  • 通过AssetReference加载
  • 使用Addressables类中的静态方法通过地址/Label加载

1.AssetReference加载的API

使用AssetReference类访问Addressable资产时无需知道他们的地址字符串,但是需要在Inspector上关联。使用流程如下:
  1. 新建一个脚本,任何可序列化的组件都支持AssetReference变量(例如,继承MonoBehaviour的脚本,ScriptableObject或其他可序列化的类)。
  2. 在组件中添加一个AssetReference类型的公共变量(例如public AssetReference explosion;)。
  3. 在Inspector中,将资产从“ Project”窗口拖到AssetReference字段上(非Addressable资产也可以拖,会自动标记为Addressable),或从项目中已经设置的可寻址资产的下拉列表中进行选择(如下所示)。
要加载或实例化AssetReference资产,需要调用其相应的方法。例如:
仅加载到内存中,多用于贴图、材质、动画、音频等资产:
[AssetReference的变量名].LoadAssetAsync<GameObject>();
直接实例化到场景中,一般用于Prefab:
[AssetReference的变量名].InstantiateAsync(pos, rot);
加载场景:
[AssetReference的变量名].LoadSceneAsync();
注:这几个API都是异步操作,异步操作详解在大智的教程中有(洪流学堂公众号中回复addr可以获取),在这就不多说了。

2. 使用Addressables类中的静态方法通过地址/Label加载

Addressables类中有加载单个资源的API和多个资源的API。
加载单个资源
在脚本中使用字符串地址加载资产,先声明using UnityEngine.AddressableAssets;名称空间,然后调用以下方法:
仅加载到内存中,多用于贴图、材质、动画、音频等资产:
Addressables.LoadAssetAsync<GameObject>("AssetAddress");
加载完成后并不会将所需的资产实例化到场景中。要将资产添加到场景中,还需要一步:实例化。
还有一个加载和实例化二合一的接口,这个接口会加载资产,然后立即将其实例化到场景中:
Addressables.InstantiateAsync("AssetAddress");
这会将指定地址的资产实例化到场景中。
注意:上面的API是异步操作。你可以在资产完成加载后提供一个回调来使用资产,异步操作详解在大智的教程中有(洪流学堂公众号中回复addr可以获取),在这就不多说了。
using System.Collections; using System.Collections.Generic; using UnityEngine.AddressableAssets; using UnityEngine; public class AddressablesExample : MonoBehaviour { GameObject myGameObject; void Start{ Addressables.LoadAssetAsync<GameObject>("AssetAddress").Completed += OnLoadDone; } private void OnLoadDone(UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle<GameObject> obj) { // In a production environment, you should add exception handling to catch scenarios such as a null result. myGameObject = obj.Result; } }
一次加载多个资产
一次加载多个资产通常是使用Label加载。
如上图所示的分组策略,可以按如下方式加载HD的皮肤贴图。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; public class TextureController : MonoBehaviour { public Renderer m_ReferencedMaterial; public void SwitchToHighDef() { LoadTexture("ArcherColor", "HD"); } void LoadTexture(string key, string label) { Addressables.LoadAssetsAsync<Texture2D>(new List<object> { key, label }, null, Addressables.MergeMode.Intersection).Completed += TextureLoaded; } void TextureLoaded(AsyncOperationHandle<IList<Texture2D>> obj) { m_ReferencedMaterial.material.mainTexture = obj.Result[0]; } }
在这一定要注意:LoadAssetsAsync有三个重载:
public static AsyncOperationHandle<IList<TObject>> LoadAssetsAsync<TObject>(object key, Action<TObject> callback); public static AsyncOperationHandle<IList<TObject>> LoadAssetsAsync<TObject>(IList<object> keys, Action<TObject> callback, MergeMode mode); public static AsyncOperationHandle<IList<TObject>> LoadAssetsAsync<TObject>(IList<IResourceLocation> locations, Action<TObject> callback);
通常我们使用前两种重载:
第一种:用于加载单个标签或地址。
第二种:用于加载地址+标签的形式。用第二种时一定要注意加上第三个参数MergeMode。否则重载匹配时就会去匹配第一个重载,会导致找不到资源。
MergeMode是什么呢?翻译过来是合并模式。
public enum MergeMode { None = 0, UseFirst = 0, Union, Intersection }
采用第二种重载加载时,其实会去先查询每一个地址/标签对应的资源,然后再根据MergeMode进行最终结果的计算。
举个栗子:
比如传入的参数是new List<object>{"cube", "red"},根据cube查询出来的资源有A、B、D,根据red查询出来的资源有C、D、E。
  • 那么MergeMode是Node或UseFirst时,会取第一个key查询到的资源:A、B、D;
  • MergeMode是Union时,会取所有key查询到的资源的并集:A、B、C、D、E;
  • MergeMode是Intersection时,会取所有key查询到的资源的交集:D。

总结

大智:“看来这个LoadAssetsAsync就是你栽了的API吧?”
小新:“没错。”
大智:“之前我都有讲过哦,一定要注意这些细节。特别是方法有重载的时候,要注意查阅API文档或者阅读源码,不能想当然。”
洪流学堂微信公众号中回复addr可以获取最新版Addressable中文手册。
Tags:
大智
你的Unity技术探路者/洪流学堂公众号主理人/XR创业者 - Student
32
Comments
大智
2 months ago
你的Unity技术探路者/洪流学堂公众号主理人/XR创业者
Y ang楼主,可以出一个addressable资源在服务器上的加载吗?而不是本地加载 或者webgl的 这些官方文档好少
0
sk
satta king
3 months ago
nice post love it http://deshawaroffice.com/
0
萌新
好啦好啦,知道啦……
0
Y ang
3 months ago
楼主,可以出一个addressable资源在服务器上的加载吗?而不是本地加载 或者webgl的 这些官方文档好少
2
Static过冬了
3 months ago
游戏开发
沙发
1