上篇简单介绍了Addresable的资源打包,这篇简单讲述一下资源加载的使用,
首先创建一个简单的测试场景,添加几个按钮,分别进行加载测试:
上面三个按钮是直接加载并响应生成事件,UI按钮是加载生成UI按钮,下面四个按钮是预加载后响应生成事件,其中Random按钮是随机生成。具体加载代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.ResourceManagement.AsyncOperations;
public class AddressableAssetLoad : MonoBehaviour
{
private string tempKey;
internal Dictionary<string, GameObject> cachePrefabDic = new Dictionary<string, GameObject>();
/// <summary>
/// 生成物体的委托
/// </summary>
public UnityAction<GameObject> InstantiateEvent;
/// <summary>
/// 加载自身资源,按钮事件
/// </summary>
/// <param name="key"></param>
public void LoadSelfAsset(string key)
{
if (!cachePrefabDic.ContainsKey(key))
{
tempKey = key;
Addressables.LoadAssetAsync<GameObject>(key).Completed += AssetsCache;
}
else
{
InstantiateEvent?.Invoke(cachePrefabDic[key]);
}
}
/// <summary>
/// 资源缓存,避免每次点击按钮都进行资源加载
/// </summary>
/// <param name="obj"></param>
private void AssetsCache(AsyncOperationHandle<GameObject> obj)
{
if (obj.IsDone)
{
if (!cachePrefabDic.ContainsValue(obj.Result))
{
if (!string.IsNullOrEmpty(tempKey))
{
cachePrefabDic.Add(tempKey, obj.Result);
tempKey = null;
}
}
}
if (obj.IsValid())
{
InstantiateEvent?.Invoke(obj.Result);
}
}
/// <summary>
/// 资源预加载
/// </summary>
/// <param name="label"></param>
private void PreloadAllAssets(string label)
{
Addressables.LoadAssetsAsync<GameObject>(label, null).Completed += AllAssetsLoadCompleted;
}
private void AllAssetsLoadCompleted(AsyncOperationHandle<IList<GameObject>> obj)
{
if (obj.Status == AsyncOperationStatus.Succeeded)
{
for (int i = 0; i < obj.Result.Count; i++)
{
if (!cachePrefabDic.ContainsValue(obj.Result[i]))
{
Debug.Log(obj.Result[i].name);
cachePrefabDic.Add(obj.Result[i].name, obj.Result[i]);
}
}
}
GetKeysTest();
}
public static AddressableAssetLoad Instance;
private void Awake()
{
Instance = this;
PreloadAllAssets("TestData");
}
private void Start()
{
InstantiateEvent = InstantiateEventTest;
}
/// <summary>
/// 生成事件
/// </summary>
/// <param name="go"></param>
private void InstantiateEventTest(GameObject go)
{
GameObject.Instantiate(go);
go.transform.rotation = Quaternion.identity;
}
/// <summary>
/// 预加载的资源地址(这里使用的资源名)
/// </summary>
public List<string> keys = new List<string>();
private void GetKeysTest()
{
foreach (var item in cachePrefabDic.Keys)
{
keys.Add(item);
}
}
/// <summary>
/// 随机加载资源
/// </summary>
public void RandomBtnEvent()
{
if (keys.Count > 0)
{
GameObject go = GameObject.Instantiate(cachePrefabDic[keys[UnityEngine.Random.Range(0, keys.Count)]]);
go.transform.position = new Vector3(go.transform.position.x + UnityEngine.Random.Range(-40, 40),
go.transform.position.y + UnityEngine.Random.Range(-40, 40),
go.transform.position.z + UnityEngine.Random.Range(-40, 40));
}
}
}
除了Random按钮绑定RandomBtnEvent事件外,其他按钮均绑定LoadSelfAsset方法,并制定对应的key(资源地址或者Label):其中UI按钮是用Label加载:
并且加载生成的是一个场景跳转的按钮,使用的AssetReference加载方式,需要手动进行制定:
具体脚本:
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;
public class SceneController : MonoBehaviour
{
public AssetReference SceneAssetReference;
private Button startBtn;
private void Awake()
{
startBtn = transform.GetComponentInChildren<Button>();
}
void Start()
{
startBtn.onClick.AddListener(() =>
{
//Addressables.LoadSceneAsync("TestScene");
SceneAssetReference.LoadSceneAsync();
});
}
}
点击就会跳转到目标场景,可加群:4364930讨论。