U3D客户端框架(资源管理篇)之AssetBundle加载器

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;
        }

    }

猜你喜欢

转载自blog.csdn.net/qq_33531923/article/details/128537420