U3D客户端框架(资源管理篇)之AssetBundle加载器
2023-09-11 14:22:31 时间
AssetBundle资源包加载器 介绍
它是资源三大加载器之一,一个非常好用的AssetBundle加载器,也可以直接通过异步的资源加载函数直接加载资源,资源加载函数会自动去查找资源所在的AB包,自动加载AB,它支持多种加载方式,File模式加载、UnityWebRequest加载,AssetBundle方式加载(在Unity5.6以上版本,请不要使用WWW加载器,它会产生内存峰值)。支持加密AB包(只建议加密敏感资源,因为会影响性能)。同时它也绕开了Unity3D早期版本的一些bug,比如多个协程并发加载同一个资源,在android系统会出错。它的冗余分析是通过解包AssetBundle进行的,这比在编辑器模式下分析的冗余更准确。
AssetBundle资源包加载器 完整代码
//AssetBundle资源包加载器
public class AssetBundleLoaderRoutine
{
//当前的资源包信息
private AssetBundleInfoEntity m_CurrAssetBundleInfo;
//资源包创建请求
private AssetBundleCreateRequest m_CurrAssetBundleCreateRequest;
//资源包创建请求(加载进度)更新
public Action<float> OnAssetBundleCreateUpdate;
//资源包加载完毕
public Action<AssetBundle> OnLoadAssetBundleComplete;
#region 加载资源包 LoadAssetBundle
public void LoadAssetBundleAsync(byte[] buffer)
{
if (m_CurrAssetBundleInfo.IsEncrypt)
{
//AssetBundle资源包加载器
public class AssetBundleLoaderRoutine
{
//当前的资源包信息
private AssetBundleInfoEntity m_CurrAssetBundleInfo;
//资源包创建请求
private AssetBundleCreateRequest m_CurrAssetBundleCreateRequest;
//资源包创建请求(加载进度)更新
public Action<float> OnAssetBundleCreateUpdate;
//资源包加载完毕
public Action<AssetBundle> OnLoadAssetBundleComplete;
#region 加载资源包 LoadAssetBundle
public void LoadAssetBundleAsync(byte[] buffer)
{
if (m_CurrAssetBundleInfo.IsEncrypt)
{
buffer = SecurityUtil.Xor(buffer);
}
//从内存加载assbundle(把byte[] 解释成AssetBundle类型)
m_CurrAssetBundleCreateRequest = AssetBundle.LoadFromMemoryAsync(buffer);
}
//加载资源包
public void LoadAssetBundle(string assetBundlePath)
{
m_CurrAssetBundleInfo = GameEntry.Resource.ResManager.GetCDNAssetBundleInfo(assetBundlePath);
//检查文件在可写区是否存在
bool isExistInLocal = GameEntry.Resource.ResManager.LocalAssetsManager.CheckFileExists(assetBundlePath);
//如果资源包存在于可写区 并且 没加密
if (isExistInLocal && !m_CurrAssetBundleInfo.IsEncrypt)
{
m_CurrAssetBundleCreateRequest = AssetBundle.LoadFromFileAsync(string.Format("{0}/{1}", Application.persistentDataPath, assetBundlePath));
}
//不存在 或者 加密了
else
{
byte[] buffer = GameEntry.Resource.ResManager.LocalAssetsManager.GetFileBuffer(assetBundlePath);
//本地无此文件
if (buffer == null)
{
//从只读区获取
GameEntry.Resource.ResManager.StreamingAssetsManager.ReadAssetBundle(assetBundlePath, (byte[] streamingFileBuffer) =>
{
//如果只读区也找不到,说明只读区没有
if (streamingFileBuffer == null)
{
GameEntry.Download.BeginDownloadSingle(assetBundlePath, onComplete: (string fileUrl) =>
{
buffer = GameEntry.Resource.ResManager.LocalAssetsManager.GetFileBuffer(fileUrl);
LoadAssetBundleAsync(buffer);
});
}
else
{
LoadAssetBundleAsync(streamingFileBuffer);
}
});
}
else
{
LoadAssetBundleAsync(buffer);
}
}
}
#endregion
//更新资源包请求(更新资源包加载)
private void UpdateAssetBundleCreateRequest()
{
if (null == m_CurrAssetBundleCreateRequest)
return;
if (m_CurrAssetBundleCreateRequest.isDone)
{
//下载完成,执行回调,通知被观察者
AssetBundle assetBundle = m_CurrAssetBundleCreateRequest.assetBundle;
if (assetBundle != null)
{
GameEntry.Log(LogCategory.Resource,"资源包=>{0} 加载完毕",m_CurrAssetBundleInfo.AssetBundleName);
//一定要早点reset,不然会出问题
Reset();
OnLoadAssetBundleComplete?.Invoke(assetBundle);
}
else
{
GameEntry.LogError("资源包=>{0} 加载失败",m_CurrAssetBundleInfo.AssetBundleName);
Reset();
OnLoadAssetBundleComplete?.Invoke(null);
}
}
else
{
//没有下载完成,回调加载进度
if (null != OnAssetBundleCreateUpdate)
{
OnAssetBundleCreateUpdate(m_CurrAssetBundleCreateRequest.progress);
}
}
}
public void OnUpdate()
{
UpdateAssetBundleCreateRequest();
}
//重置
public void Reset()
{
m_CurrAssetBundleCreateRequest = null;
}
} buffer = SecurityUtil.Xor(buffer);
}
//从内存加载assbundle(把byte[] 解释成AssetBundle类型)
m_CurrAssetBundleCreateRequest = AssetBundle.LoadFromMemoryAsync(buffer);
}
//加载资源包
public void LoadAssetBundle(string assetBundlePath)
{
m_CurrAssetBundleInfo = GameEntry.Resource.ResManager.GetCDNAssetBundleInfo(assetBundlePath);
//检查文件在可写区是否存在
bool isExistInLocal = GameEntry.Resource.ResManager.LocalAssetsManager.CheckFileExists(assetBundlePath);
//如果资源包存在于可写区 并且 没加密
if (isExistInLocal && !m_CurrAssetBundleInfo.IsEncrypt)
{
m_CurrAssetBundleCreateRequest = AssetBundle.LoadFromFileAsync(string.Format("{0}/{1}", Application.persistentDataPath, assetBundlePath));
}
//不存在 或者 加密了
else
{
byte[] buffer = GameEntry.Resource.ResManager.LocalAssetsManager.GetFileBuffer(assetBundlePath);
//本地无此文件
if (buffer == null)
{
//从只读区获取
GameEntry.Resource.ResManager.StreamingAssetsManager.ReadAssetBundle(assetBundlePath, (byte[] streamingFileBuffer) =>
{
//如果只读区也找不到,说明只读区没有
if (streamingFileBuffer == null)
{
GameEntry.Download.BeginDownloadSingle(assetBundlePath, onComplete: (string fileUrl) =>
{
buffer = GameEntry.Resource.ResManager.LocalAssetsManager.GetFileBuffer(fileUrl);
LoadAssetBundleAsync(buffer);
});
}
else
{
LoadAssetBundleAsync(streamingFileBuffer);
}
});
}
else
{
LoadAssetBundleAsync(buffer);
}
}
}
#endregion
//更新资源包请求(更新资源包加载)
private void UpdateAssetBundleCreateRequest()
{
if (null == m_CurrAssetBundleCreateRequest)
return;
if (m_CurrAssetBundleCreateRequest.isDone)
{
//下载完成,执行回调,通知被观察者
AssetBundle assetBundle = m_CurrAssetBundleCreateRequest.assetBundle;
if (assetBundle != null)
{
GameEntry.Log(LogCategory.Resource,"资源包=>{0} 加载完毕",m_CurrAssetBundleInfo.AssetBundleName);
//一定要早点reset,不然会出问题
Reset();
OnLoadAssetBundleComplete?.Invoke(assetBundle);
}
else
{
GameEntry.LogError("资源包=>{0} 加载失败",m_CurrAssetBundleInfo.AssetBundleName);
Reset();
OnLoadAssetBundleComplete?.Invoke(null);
}
}
else
{
//没有下载完成,回调加载进度
if (null != OnAssetBundleCreateUpdate)
{
OnAssetBundleCreateUpdate(m_CurrAssetBundleCreateRequest.progress);
}
}
}
public void OnUpdate()
{
UpdateAssetBundleCreateRequest();
}
//重置
public void Reset()
{
m_CurrAssetBundleCreateRequest = null;
}
}
相关文章
- Redis 客户端安装与远程连接图解
- 如何在mysql客户端即mysql提示符下执行操作系统命令
- 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq
- windows 上rsync客户端使用方法
- 77分布式电商项目 - CAS 客户端与 SpringSecurity 集成
- 客户端的socket是否需要bind?
- 新闻段子客户端
- 在PL/SQL/sqlplus客户端 中如何让程序暂停几秒钟
- 原生java调用webservice的方法,不用生成客户端代码
- 基于java的一款实时聊天系统,包含服务端 + 客户端 + web端
- Linux的ssh客户端
- Cocos2dx:简单的PHP后端服务器+lua socket客户端连接
- 新浪微博开放平台开发-android客户端(1)【转】
- HttpClientFactory in ASP.NET Core 2.1 Part 2:定义命名和类型化的客户端
- U3D客户端框架(资源管理篇)之自动化打Assetbundle包管理器
- U3D客户端框架(资源管理篇)之可写区资源管理器
- U3D客户端框架之实现基于UnityWebRequest的Http服务 实现HttpCallBackArgs参数类、HttpRoutine访问器、HttpManager管理器
- U3D客户端框架之 拓展StringBuilder实现InsertNoGC、IndexOf、LastIndexOf、ReplaceNoGC、AppendNoGC API 减少GC
- U3D客户端框架之封装 DeviceUtil 获取设备唯一ID和设备型号
- FTP客户端连接失败,提示“530 Authentication failed” (原)
- C#项目类型分三种,Dos(控制台),c/s(客户端与服务器),b/s(浏览器/服务器)