赞
踩
资源加载管理器模块的主要职责就是资源加载的管理,从物理结构上对该模块进行了拆分成了一个单独的文件,资源加载管理器是加载器中偏底层的一个部分;资源加载管理器负责AssetBundle的加载、Asset资源的加载、资源加载完成后缓存进对预制池、卸载功能;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using YouYou;
- using UnityEngine;
-
- namespace Myh
- {
- //资源加载管理
- public class ResourceLoaderManager : ManagerBase, IDisposable
- {
- //资源加载管理器
- //资源分类:{资源名:资源实体}
- private Dictionary<AssetCategory, Dictionary<string, AssetEntity>> m_dicAssetInfo;
-
- //资源包加载器链表
- private LinkedList<AssetBundleLoaderRoutine> m_ListAssetBundleLoader;
-
- //资源加载链表
- private LinkedList<AssetLoaderRoutine> m_ListAssetLoader;
-
- //加载中的资源
- private Dictionary<string, LinkedList<Action<UnityEngine.Object>>> m_dicLoadingAsset = new Dictionary<string, LinkedList<Action<UnityEngine.Object>>>();
-
- //初始化资源信息完毕
- private BaseAction m_InitAssetInfoComplete;
-
- private Dictionary<string, LinkedList<Action<AssetBundle>>> m_dicLoadingAssetBundle = new Dictionary<string, LinkedList<Action<AssetBundle>>>();
-
- public ResourceLoaderManager()
- {
- m_dicAssetInfo = new Dictionary<AssetCategory, Dictionary<string, AssetEntity>>();
- m_ListAssetBundleLoader = new LinkedList<AssetBundleLoaderRoutine>();
- m_ListAssetLoader = new LinkedList<AssetLoaderRoutine>();
- }
-
- //初始化
- public override void Init()
- {
- //确保游戏刚开始运行的时候,分类字典已经初始化好了
- IEnumerator iter = Enum.GetValues(typeof(AssetCategory)).GetEnumerator();
- while (iter.MoveNext())
- {
- AssetCategory assetCategory = (AssetCategory)iter.Current;
- m_dicAssetInfo[assetCategory] = new Dictionary<string, AssetEntity>();
- }
- }
-
- #region 初始化资源信息
- //初始化资源信息(这个才是真正的初始化函数)
- private void InitAssetInfo(byte[] buffer)
- {
- buffer = ZlibHelper.DeCompressBytes(buffer);
-
- MMO_MemoryStream ms = new MMO_MemoryStream(buffer);
- int len = ms.ReadInt();
- int depLen = 0;
-
- for (int i = 0; i < len; ++i)
- {
- AssetEntity entity = new AssetEntity();
- entity.Category = (AssetCategory)ms.ReadByte();
- entity.AssetFullName = ms.ReadUTF8String();
- entity.AssetBundleName = ms.ReadUTF8String();
- depLen = ms.ReadInt();
-
- //有依赖的资源包
- if (depLen > 0)
- {
- entity.ListDependsAsset = new List<AssetDependsEntity>();
-
- //对依赖的资源包进行循环
- for (int j = 0; j < depLen; ++j)
- {
- AssetDependsEntity assetDependsEntity = new AssetDependsEntity();
- assetDependsEntity.Category = (AssetCategory)ms.ReadByte();
- assetDependsEntity.AssetFullName = ms.ReadUTF8String();
- entity.ListDependsAsset.Add(assetDependsEntity);
- }
- }
- m_dicAssetInfo[entity.Category][entity.AssetFullName] = entity;
- }
-
- m_InitAssetInfoComplete?.Invoke();
- }
-
- //从CDN加载资源信息
- private void OnLoadAssetInfoFromCDN(HttpCallBackArgs args)
- {
- if (!args.HasError)
- {
- InitAssetInfo(args.Data);
- }
- else
- {
- GameEntry.Log(LogCategory.Resource, args.Value);
- }
- }
-
- #region 初始化资源信息
-
- //初始化资源信息
- public void InitAssetInfo(BaseAction initAssetInfoComplete)
- {
- m_InitAssetInfoComplete = initAssetInfoComplete;
-
- //资源信息?
- byte[] buffer = GameEntry.Resource.ResManager.LocalAssetsManager.GetFileBuffer(ConstDefine.AssetInfoName);
-
- if (buffer == null)
- {
- //如果只读区没有,从CDN读
- string url = string.Format("{0}{1}", GameEntry.Data.SysDataManager.CurrChannelConfig.RealSourceUrl, ConstDefine.AssetInfoName);
- GameEntry.Http.SendData(url, OnLoadAssetInfoFromCDN, isGetData: true);
- }
- else
- {
- InitAssetInfo(buffer);
- }
- }
-
- //根据资源分类和资源路径 获取资源信息
- public AssetEntity GetAssetEntity(AssetCategory assetCategory, string assetFullName)
- {
- Dictionary<string, AssetEntity> dicCategory = null;
- if (m_dicAssetInfo.TryGetValue(assetCategory, out dicCategory))
- {
- AssetEntity entity = null;
- if (dicCategory.TryGetValue(assetFullName, out entity))
- {
- return entity;
- }
- }
- return null;
- }
- #endregion
-
- #endregion
-
- #region 加载资源包 LoadAssetBundle
- //加载中的资源包
- //{资源包名:加载资源包完成的回调list}
-
- /// <summary>
- /// 加载资源包
- /// </summary>
- /// <param name="assetBundlePath">ab包路径</param>
- /// <param name="onUpdate">加载中回调</param>
- /// <param name="onComplete">加载完成回调</param>
- public void LoadAssetBundle(string assetBundlePath, Action<float> onUpdate = null, Action<AssetBundle> onComplete = null)
- {
- //1.判断资源包是否存在于AssetBundlePool中
- ResourceEntity resourceEntity = GameEntry.Pool.AssetBundlePool.Spawn(assetBundlePath);
-
- //资源在资源包池中 存在
- if (resourceEntity != null)
- {
- AssetBundle assetBundle = resourceEntity.Target as AssetBundle;
- onComplete?.Invoke(assetBundle);
- return;
- }
-
- //资源在资源包池中 不存在
- LinkedList<Action<AssetBundle>> lst = null;
- if (m_dicLoadingAssetBundle.TryGetValue(assetBundlePath, out lst))
- {
- //如果存在加载中的assetbundle,把加载完成的回调函数 加入这个资源加载的链表,然后返回
- lst.AddLast(onComplete);
- return;
- }
- else
- {
- lst = GameEntry.Pool.DequeueClassObject<LinkedList<Action<AssetBundle>>>();
- lst.AddLast(onComplete);
- m_dicLoadingAssetBundle[assetBundlePath] = lst;
- }
-
- //资源包加载routine
- AssetBundleLoaderRoutine routine = GameEntry.Pool.DequeueClassObject<AssetBundleLoaderRoutine>();
- //这句话可以不加,Dequeue的时候如果没有一定会new一个
- if (null == routine)
- {
- routine = new AssetBundleLoaderRoutine();
- }
-
- //加入链表还是循环加载
- m_ListAssetBundleLoader.AddLast(routine);
-
- //开始加载assetBundle
- routine.LoadAssetBundle(assetBundlePath);
-
- //注册更新回调
- routine.OnAssetBundleCreateUpdate = (float progress) =>
- {
- onUpdate?.Invoke(progress);
- };
-
- routine.OnLoadAssetBundleComplete = (AssetBundle assetBundle) =>
- {
- //把资源包注册到资源池
- resourceEntity = GameEntry.Pool.DequeueClassObject<ResourceEntity>();
- resourceEntity.ResourceName = assetBundlePath;
- resourceEntity.IsAssetBundle = true;
- resourceEntity.Target = assetBundle;
- GameEntry.Pool.AssetBundlePool.Register(resourceEntity);
-
- //加载完成后,执行所有回调函数
- for (LinkedListNode<Action<AssetBundle>> iter = lst.First; iter != null; iter = iter.Next)
- {
- iter.Value?.Invoke(assetBundle);
- }
-
- //一定要清空
- lst.Clear();
-
- GameEntry.Pool.EnqueueClassObject(lst);
-
- //下载完成后,从下载中字段中清除这个字典
- m_dicLoadingAssetBundle.Remove(assetBundlePath);
-
- //结束循环 routine回池
- m_ListAssetBundleLoader.Remove(routine);
- GameEntry.Pool.EnqueueClassObject(routine);
- };
- }
-
- #endregion
-
- #region 从资源包中加载资源 LoadAsset
- /// <param name="assetName">资源名</param>
- /// <param name="assetBundle">assetBundle包</param>
- /// <param name="onUpdate">加载中回调</param>
- /// <param name="onComplete">加载完成回调</param>
- public void LoadAsset(string assetName, AssetBundle assetBundle, Action<float> onUpdate = null, Action<UnityEngine.Object> onComplete = null)
- {
- LinkedList<Action<UnityEngine.Object>> lst = null;
-
- //这个资源在加载中
- if (m_dicLoadingAsset.TryGetValue(assetName, out lst))
- {
- //把加载完成回调函数(委托)加入到对应的链表中,然后直接返回
- lst.AddLast(onComplete);
- return;
- }
- else
- {
- //如果不在加载中
- //从类对象池取一个对象,把链表保存到字典中
- lst = GameEntry.Pool.DequeueClassObject<LinkedList<Action<UnityEngine.Object>>>();
- lst.AddLast(onComplete);
- m_dicLoadingAsset[assetName] = lst;
- }
-
- AssetLoaderRoutine routine = GameEntry.Pool.DequeueClassObject<AssetLoaderRoutine>();
- if (routine == null)
- routine = new AssetLoaderRoutine();
-
- m_ListAssetLoader.AddLast(routine);
-
- //开始加载资源
- routine.LoadAsset(assetName, assetBundle);
-
- //下载中更新回调
- routine.OnAssetUpdate = (float progress) =>
- {
- onUpdate?.Invoke(progress);
- };
-
- //下载完成回调
- routine.OnLoadAssetComplete = (UnityEngine.Object obj) =>
- {
- for (LinkedListNode<Action<UnityEngine.Object>> iter = lst.First; iter != null; iter = iter.Next)
- {
- iter.Value?.Invoke(obj);
- }
-
- //一定要清空
- lst.Clear();
-
- //链表回池
- GameEntry.Pool.EnqueueClassObject(lst);
-
- //资源对应的链表从字典删除
- m_dicLoadingAsset.Remove(assetName);
-
- //结束循环
- m_ListAssetLoader.Remove(routine);
-
- //资源加载器回池
- GameEntry.Pool.EnqueueClassObject(routine);
- };
-
- }
- #endregion
-
-
- /// <summary>
- /// 加载主资源
- /// </summary>
- /// <param name="assetCategory">资源分类</param>
- /// <param name="assetFullName">资源完整名称</param>
- /// <param name="onComplete">加载完成回调</param>
- public void LoadMainAsset(AssetCategory assetCategory, string assetFullName, BaseAction<ResourceEntity> onComplete = null)
- {
- MainAssetLoaderRoutine routine = GameEntry.Pool.DequeueClassObject<MainAssetLoaderRoutine>();
-
- //加载
- routine.LoadAsset(assetCategory, assetFullName,(ResourceEntity resEntity)=>
- {
- onComplete?.Invoke(resEntity);
- });
- }
-
- //释放资源
- public void UnLoadGameObject(GameObject go)
- {
- GameEntry.Pool.ReleaseInstanceResource(go.GetInstanceID());
- }
-
- // 更新所有 AssetBundleLoaderRoutine
- // 更新所有 AssetLoaderRoutine
- public void OnUpdate()
- {
- for (LinkedListNode<AssetBundleLoaderRoutine> iter = m_ListAssetBundleLoader.First; iter!=null; iter= iter.Next)
- {
- iter.Value.OnUpdate();
- }
-
- for (LinkedListNode<AssetLoaderRoutine> iter = m_ListAssetLoader.First; iter != null; iter = iter.Next)
- {
- iter.Value.OnUpdate();
- }
- }
-
- public void Dispose()
- {
- m_dicAssetInfo.Clear();
- m_ListAssetBundleLoader.Clear();
- m_ListAssetLoader.Clear();
- }
-
-
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。