文章目录
- 1 引用加载
- 1.1 Addressables 的资源引用类
- 1.2 加载资源
- 1.3 加载场景
- 1.4 释放资源
- 2 Label 介绍
- 3 动态加载
- 3.1 加载单个资源
- 3.2 加载多个资源
- Unity 版本:6000.0.26f1c1
- Addressables 版本:2.3.1
1 引用加载
1.1 Addressables 的资源引用类
AssetReference
:通用资源引用类,可加载任意类型资源。AssetReferenceAtlasedSprite
:图集资源引用类。AssetReferenceGameObject
:游戏对象资源引用类。AssetReferenceSprite
:精灵图片资源引用类。AssetReferenceTexture
:贴图资源引用类。AssetReferenceT<>
:指定类型引用类。
通过申明不同类型引用类对象,可以在 Inspector 窗口中筛选关联的 Addressables 对象。
public class Lesson3 : MonoBehaviour
{public AssetReference AssetReference;public AssetReferenceAtlasedSprite AssetReferenceAtlasedSprite;public AssetReferenceGameObject AssetReferenceGameObject;public AssetReferenceSprite AssetReferenceSprite;public AssetReferenceTexture AssetReferenceTexture;public AssetReferenceT<AudioClip> AssetReferenceTAudioClip;public AssetReferenceT<RuntimeAnimatorController> AssetReferenceTRuntimeAnimatorController;public AssetReferenceT<TextAsset> AssetReferenceTTextAsset;public AssetReferenceT<Material> AssetReferenceTMaterialRed;public AssetReference AssetReferenceTScene;
}
1.2 加载资源
注意:所有 Addressables 加载相关都使用异步加载。
需要引用命名空间:
using UnityEngine.ResourceManagement.AsyncOperations;
public class Lesson3 : MonoBehaviour
{public AssetReference AssetReference;...// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){// 1. 使用异步操作句柄AsyncOperationHandle<GameObject> handle = assetReference.LoadAssetAsync<GameObject>();handle.Completed += TestFun;// 2. 简化写法AssetReference.LoadAssetAsync<GameObject>().Completed += handle =>{// 判断是否加载成功// 建议使用传入参数if (handle.Status == AsyncOperationStatus.Succeeded){var obj = Instantiate(handle.Result);obj.name = "Loaded GameObject";}// 不建议使用标识类创建// if(assetReference.IsDone)// {// Instantiate(assetReference.Asset);// }};}private void TestFun(AsyncOperationHandle<GameObject> handle){// 加载成功后,使用加载的资源嘛// 判断是否加载成功if(handle.Status == AsyncOperationStatus.Succeeded){Instantiate(handle.Result);}}
}
1.3 加载场景
public class Lesson3 : MonoBehaviour
{public AssetReference AssetReferenceTScene; // 需要引用 Scene 资源...// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){AssetReferenceTScene.LoadSceneAsync().Completed += (handle) =>{// 初始化场景的一些信息print("场景加载结束");};}
}
1.4 释放资源
AssetReference.ReleaseAsset();
- 释放资源方法后,资源引用类中的资源会置空,但是 AsyncOperationHandle 类中的对象不为空。
- 释放资源不会影响场景中被实例化出来的对象,但是会影响使用的资源。
public class Lesson3 : MonoBehaviour
{public AssetReference AssetReference;...// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){AssetReference.LoadAssetAsync<GameObject>().Completed += handle =>{if (handle.Status == AsyncOperationStatus.Succeeded){var obj = Instantiate(handle.Result);obj.name = "Loaded GameObject";// 加载完成后,释放资源AssetReference.ReleaseAsset();Debug.Log(handle.Result == null); // falseDebug.Log(AssetReference.Asset == null); // true}};}
}
2 Label 介绍
引用加载必须在脚本中声明各种引用类来指定加载的资源,不够灵活,只适合做一些小项目。
实际商业项目开发中,很多时候根据配置文件决定加载的资源,即动态加载。
通过给定名称和标签,来加载指定资源。
Label 作用举例:
游戏装备中有一顶帽子:Hat,拥有不同的品质,比如:红、绿、白、蓝。
通过标签 Label 来区分,Label 分别是:Red、Green、White、Blue。
游戏中根据设备好坏选择不同质量的图片或者模型,比如:高清、标清、超清。
但在不同标准下,这些模型的命名应该是相同的,Label 分别是:HD、SD、FHD。
游戏中逢年过节时更换模型和 UI 显示,比如:中秋节、春节、圣诞节。
不同节日时角色或者 UI 等资源看起来是不同的,但资源的命名应该都遵循同样的规范。
比如登录面板,在中秋节、春节、圣诞节时它的资源名都是登录面板,Label 分别可以是:MidAutumn、Spring、Christmas。
3 动态加载
-
命名空间:
UnityEngine.AddressableAssets
UnityEngine.ResourceManagement.AsyncOperations
以下是打包示例:
3.1 加载单个资源
(1)通过资源名或标签名动态加载单个资源
public static AsyncOperationHandle<TObject> LoadAssetAsync<TObject>(object key);
注意:
- 如果存在同名或同标签的同类型资源,会自动加载第一个满足条件的对象。
- 如果存在同名或同标签的不同类型资源,可以根据泛型类型来决定加载哪一个。
以加载标签为 “Red” 的 GameObject 资源为例:
public class Lesson5 : MonoBehaviour
{// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){Addressables.LoadAssetAsync<GameObject>("Red").Completed += handle =>{if (handle.Status == AsyncOperationStatus.Succeeded){Instantiate(handle.Result);}};}
}
以加载名称为 “Red” 的 GameObject 资源为例:
public class Lesson5 : MonoBehaviour
{// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){Addressables.LoadAssetAsync<GameObject>("Cube").Completed += handle =>{if (handle.Status == AsyncOperationStatus.Succeeded){Instantiate(handle.Result);}};}
}
(2)动态加载场景
public static AsyncOperationHandle<SceneInstance> LoadSceneAsync(
object key,
LoadSceneMode loadMode = LoadSceneMode.Single,
bool activateOnLoad = true,
int priority = 100,
SceneReleaseMode releaseMode = SceneReleaseMode.ReleaseSceneWhenSceneUnloaded
);
- key:场景名。
- loadMode:加载模式。
- LoadSceneMode.Single:单独加载,只保留新加载的场景;
- LoadSceneMode.Additive:叠加加载,两个场景一起显示(不常用)。
- activateOnLoad:场景加载是否激活。如果为 false,加载完成后不会直接切换,需要自己使用返回值中的 ActivateAsync 方法。
- priority:场景加载的异步操作优先级。
- releaseMode:释放模式。
- SceneReleaseMode.ReleaseSceneWhenSceneUnloaded:卸载场景时释放;
- SceneReleaseMode.OnlyReleaseSceneOnHandleRelease:手动释放。
例如,加载 SampleScene 场景并手动激活:
public class Lesson5 : MonoBehaviour
{// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){Addressables.LoadSceneAsync("SampleScene", LoadSceneMode.Single, false, 100).Completed += (obj) =>{// 手动激活场景obj.Result.ActivateAsync();};}
}
(3)释放资源
public static void Release<TObject>(AsyncOperationHandle<TObject> handle)
释放资源时,需要记录加载后的 Handle。
public class Lesson5 : MonoBehaviour
{public AsyncOperationHandle<GameObject> Handle;// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){Handle = Addressables.LoadAssetAsync<GameObject>("Cube");Handle.Completed += operationHandle =>{if (operationHandle.Status == AsyncOperationStatus.Succeeded){Instantiate(operationHandle.Result);// 加载完成后,释放资源Addressables.Release(Handle);}};}
}
注意:
一定要保证资源使用完毕过后再释放资源。
建议将 Play Mode Script 改为 “Use Existing Build” 测试,因为 “Use Asset Database” 模式下,不会真正地从 AB 包释放资源。
3.2 加载多个资源
(1)重载一
public static AsyncOperationHandle<IList<TObject>> LoadAssetsAsync<TObject>(
object key,
Action<TObject> callback,
bool releaseDependenciesOnFailure
);
- key:资源名或标签名。
- callback:每个加载资源结束后会调用的函数,会把加载到的资源传入该函数中。
- releaseDependenciesOnFailure:为 true,当资源加载失败时自动将已加载的资源和依赖释放;为 false,需要自己手动来管理释放。
public class Lesson6 : MonoBehaviour
{// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){var handle = Addressables.LoadAssetsAsync<GameObject>("Red", obj =>{// (1):应用于每个 GameObject,与 (2) 等价Debug.Log(obj.name);}, true);// (2):遍历 GameObject 列表,与 (1) 等价handle.Completed += (obj) =>{foreach (var o in obj.Result){Debug.Log(o.name);}};}
}
(2)重载二
public static AsyncOperationHandle<IList<TObject>> LoadAssetsAsync<TObject>(
IEnumerable keys,
Action<TObject> callback,
MergeMode mode,
bool releaseDependenciesOnFailure
);
-
keys:想要加载资源的条件列表(资源名、Lable 名)。
-
callback:每个加载资源结束后会调用的函数,会把加载到的资源传入该函数中。
-
mode:可寻址的合并模式,用于合并请求结果的选项。
如果键 “Cube”、“Red” 分别对应结果 [1, 2, 3]、[1, 3, 4](数字代表不同的资源):
- MergeMode.None:不发生合并,将使用第一组结果 结果为 [1, 2, 3];
- MergeMode.UseFirst:应用第一组结果,结果为 [1, 2, 3];
- MergeMode.Union:合并所有结果,结果为 [1, 2, 3, 4];
- MergeMode.Intersection:使用相交结果,结果为 [1, 3]。
-
releaseDependenciesOnFailure:为 true,当资源加载失败时自动将已加载的资源和依赖释放;为 false,需要自己手动来管理释放。
public class Lesson6 : MonoBehaviour
{// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){Addressables.LoadAssetsAsync<Object>(new[] { "Cube", "Red" },obj => { Debug.Log(obj.name); }, // 打印结果:"Cube"Addressables.MergeMode.Intersection,true);}
}