做过好多次这种东西了,每次都要从原生API开始集成,所以这次就记录一下工具方法。
虽然现在Addressable已经出来了,但是可能有些细节上的东西Addressable没有覆盖到,或者有些项目没有使用Addressable,所以这些方法就还有点用
本地ab包的同步加载
本地ab包的异步加载
遇到了两个问题
异步回调的返回ab包当前是否还需要
can’t be loaded because another AssetBundle with the same files is already loaded.
查了下报错,原来我很久以前遇见过
Unity 加载 AB包的缓存问题
正在异步加载assetbundle的过程中,又去加载另个assetbundle,即使两个ab包毫不相干。
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Events;
public class AssetBundleUtil : MonoBehaviour
{
static AssetBundleUtil instance;
public static AssetBundleUtil Instance => instance;
private void Awake()
{
instance = this;
}
public static bool TryLoadAssetByAB<T>(string path, out T resultAsset) where T : UnityEngine.Object
{
string abFilePath = path.Substring(0, path.LastIndexOf(".")) + ".ab";
FileInfo abFileInfo = new FileInfo(abFilePath);
if (!abFileInfo.Exists)
{
Debug.Log("文件不存在,路径:" + abFileInfo.FullName);
resultAsset = null;
return false;
}
else
{
string fileSimpleName = abFileInfo.Name.Split('.')[0];
AssetBundle assetBundle = AssetBundle.LoadFromFile(abFileInfo.FullName);
resultAsset = assetBundle.LoadAsset(fileSimpleName) as T;
assetBundle.Unload(false);
return true;
}
}
public void TryLoadAssetByABAsync<ToLoadObjectType>(string path, UnityAction<ToLoadObjectType> resultAsset)
where ToLoadObjectType : UnityEngine.Object
{
StartCoroutine(LoadAssetByABAsync(path, resultAsset));
}
IEnumerator LoadAssetByABAsync<ToLoadObjectType>(string path, UnityAction<ToLoadObjectType> resultAsset)
where ToLoadObjectType : UnityEngine.Object
{
string abFilePath = path.Substring(0, path.LastIndexOf(".")) + ".ab";
AssetBundleCreateRequest assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(path);
yield return assetBundleCreateRequest;
FileInfo abFileInfo = new FileInfo(abFilePath);
var assetBundle = assetBundleCreateRequest.assetBundle;
if (assetBundle == null)
{
Debug.Log("加载错误");
yield break;
}
string fileSimpleName = abFileInfo.Name.Split('.')[0];
var assetLoadRequest = assetBundle.LoadAssetAsync<ToLoadObjectType>(fileSimpleName);
yield return assetLoadRequest;
if (assetLoadRequest.isDone )
{
ToLoadObjectType toLoadObjectType = assetLoadRequest.asset as ToLoadObjectType;
if (toLoadObjectType != null)
{
resultAsset?.Invoke(toLoadObjectType);
}
}
assetBundle.Unload(false);
}
}
|