Addressable-动态加载单个资源
1、通过资源名或标签名动态加载、释放单个资源
// 通过资源名
handle = Addressables.LoadAssetAsync<GameObject>("Cube");
handle.Completed += (handle) =>
{//判断加载成功if (handle.Status == AsyncOperationStatus.Succeeded)Instantiate(handle.Result);//一定要是 加载完成后 使用完毕后 再去释放//不管任何资源 只要释放后 都会影响之前在使用该资源的对象// 可以在 OnDstroy 中调用Addressables.Release(handle);
};// 通过Label
Addressables.LoadAssetAsync<GameObject>("Red").Completed += (handle) =>
{//判断加载成功if (handle.Status == AsyncOperationStatus.Succeeded)Instantiate(handle.Result);
};
注意:
- 如果存在同名或同标签的同类型资源,我们无法确定加载的哪一个,它会自动加载找到的第一个满足条件的对象
- 如果存在同名或同标签的不同类型资源,我们可以根据泛型类型来决定加载哪一个
2、动态加载场景
参数一:场景名
参数二:加载模式 (叠加还是单独,叠加就是两个场景一起显示,单独就是只保留新加载的场景,正常情况为单独)
参数三:场景加载是否激活,如果为false,加载完成后不会直接切换,需要自己使用返回值中的ActivateAsync方法
参数四:场景加载的异步操作优先级
Addressables.LoadSceneAsync("SampleScene", UnityEngine.SceneManagement.LoadSceneMode.Single, false).Completed += (obj)=> {//比如说 手动激活场景obj.Result.ActivateAsync().completed += (a) =>{//然后再去创建场景上的对象//然后再去隐藏 加载界面//注意:场景资源也是可以释放的,并不会影响当前已经加载出来的场景,因为场景的本质只是配置文件Addressables.Release(obj);};
};
3、AddressableMgr
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;public class AddressableMgr
{public static AddressableMgr instance = new AddressableMgr();public static AddressableMgr Instance => instance;// 有一个容帮助存储异步加载的返回值public Dictionary<string, IEnumerator> resDic = new Dictionary<string, IEnumerator>();private AddressableMgr() { }public void LoadAssetAsync<T>(string name, Action<AsyncOperationHandle<T>> callback){// 由于存在同名,不同类型资源区分加载,所以通过名字和类型进行拼接作为 Keystring keyName = name + "_" + typeof(T).Name;AsyncOperationHandle<T> handle;// 已经加载过该资源if (resDic.ContainsKey(keyName)){// 获取异步加载返回的 handlehandle = (AsyncOperationHandle<T>)resDic[keyName];if (handle.IsDone){callback(handle);}// 还没有加载完成else {// 如果还没有异步加载完成,只需要添加委托告诉完成后做什么handle.Completed += (obj) =>{if (obj.Status == AsyncOperationStatus.Succeeded)callback(obj);};}return;}// 如果没有加载过该资源,直接进行异步加载并记录handle = Addressables.LoadAssetAsync<T>(name);handle.Completed += (obj) =>{if (obj.Status == AsyncOperationStatus.Succeeded)callback(obj);else{Debug.LogWarning(keyName + " load asset failed");if (resDic.ContainsKey(keyName))resDic.Remove(keyName);}};resDic[keyName] = handle;}public void Release<T>(string name){string keyName = name + "_" + typeof(T).Name;if (resDic.ContainsKey(keyName)){AsyncOperationHandle<T> handle = (AsyncOperationHandle <T>)resDic[keyName];Addressables.Release(handle);resDic.Remove(keyName);}}public void Clear(){resDic.Clear();AssetBundle.UnloadAllAssetBundles(true);Resources.UnloadUnusedAssets();GC.Collect();}}