123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- namespace Engine.CLoader
- {
- /// <summary>客户端加载对象处理器器</summary>
- public class CLoaderManager : MonoBehaviour
- {
- #region 单利
- private static CLoaderManager instance;
- /// <summary>单利对象</summary>
- public static CLoaderManager GetInstance()
- {
- if (instance == null)
- {
- GameObject managerGO = new GameObject();
- DontDestroyOnLoad(managerGO);
- managerGO.name = "CLoaderManager";
- instance = managerGO.AddComponent<CLoaderManager>();
- }
- return instance;
- }
- #endregion
- /// <summary>缓存的loader对象列表</summary>
- private List<CLoaderAB> catchLoaderList = new List<CLoaderAB>();
- /// <summary>当前缓存的资源</summary>
- private List<CAssetsInfo> catchAssetsList = new List<CAssetsInfo>();
- /// <summary>现在中的loader个数</summary>
- private int loadIngLoaderCount = 0;
- /// <summary>是否初始化了处理器</summary>
- public bool IsInitManager = false;
- /// <summary>空构造函数</summary>
- public CLoaderManager() { }
- /// <summary>初始化处理器</summary>
- public void InitManager(CLoaderData configData)
- {
- //创建Loader对象
- CreateCatchLoader();
- //加载配置文件
- this.LoadAssets(configData);
- }
- /// <summary>预先创建加载对象</summary>
- private void CreateCatchLoader()
- {
- for (int i = 0; i < CLoaderConst.CLoaderMaxCount; i++)
- {
- catchLoaderList.Add(new CLoaderAB());
- }
- }
- /// <summary>回收内存</summary>
- public void GC()
- {
- //Resources.UnloadUnusedAssets ();
- }
- /// <summary>添加资源</summary>
- private void AddAssets(CLoaderAB loader)
- {
- CAssetsInfo assetsInfo = FindEmptyAssets();
- if(assetsInfo==null)
- {
- assetsInfo = new CAssetsInfo();
- catchAssetsList.Add(assetsInfo);
- }
- assetsInfo.assetsBundle = loader.assetsBundle;
- assetsInfo.assetsName = loader.assetsName;
- assetsInfo.isEmpty = false;
- }
- /// <summary>查找获得名称的资源包数据</summary>
- internal CAssetsInfo GetAssets(string assetsName)
- {
- CAssetsInfo assetsInfo = this.FindAssetsByAssetsName(assetsName);
- if (assetsInfo != null)
- {
- assetsInfo.AddUseCount();
- }
- return assetsInfo;
- }
- /// <summary>查找一个空的CAssetsInfo</summary>
- private CAssetsInfo FindEmptyAssets()
- {
- for (int i = 0; i < catchAssetsList.Count; i++)
- {
- if(catchAssetsList[i].isEmpty)
- {
- return catchAssetsList[i];
- }
- }
- return null;
- }
- /// <summary>查找指定名称的资源</summary>
- private CAssetsInfo FindAssetsByAssetsName(string assetsName)
- {
- for (int i = 0; i < catchAssetsList.Count; i++)
- {
- if (catchAssetsList[i].assetsName == assetsName)
- {
- return catchAssetsList[i];
- }
- }
- return null;
- }
- /// <summary>等待执行的loaderData,下载逻辑是两层队列,这是第一层队列</summary>
- private List<CLoaderData> waitLoadDataList = new List<CLoaderData>();
- /// <summary>实际需要下载的资源</summary>
- private List<string> waitNeedLoadAssets = new List<string>();
- /// <summary>加载资源</summary>
- public void LoadAssets(CLoaderData loaderData)
- {
- //添加到队列
- waitLoadDataList.Add(loaderData);
- //执行一个LoadData
- if (waitLoadDataList.Count == 1)
- {
- this.LoadFistLoaderData();
- }
- }
- /// <summary>加载第一个CLoaderData</summary>
- private void LoadFistLoaderData()
- {
- if(waitLoadDataList.Count==0)
- { return; }
- //获得数据
- CLoaderData loaderData = waitLoadDataList[0];
- //循环长度
- int forLeng = 0;
- //不是配置文件
- if (loaderData.assetsType != AssetsType.Config)
- {
- //如果有依赖的包先下载依赖的包
- List<CAssetsConfigInfo> assetsConfigList = loaderData.AssetsConfigList;
- forLeng = assetsConfigList.Count;
- bool isDataComplete = false;
- for (int i = 0; i < forLeng; i++)
- {
- if(LoadDepAssets(assetsConfigList[i], assetsConfigList[i]))
- {
- isDataComplete = true;
- break;
- }
- }
- if(isDataComplete)
- {
- OnFirstLoaderComplete();
- }
- }
- //资源配置文件,这时还获取不到资源的配置数据
- else
- {
- forLeng = loaderData.listAssetsName.Count;
- for (int i = 0; i < forLeng; i++)
- {
- this.AddNeedLoadAssets(loaderData.listAssetsName[i]);
- }
- }
- }
- /// <summary>递归次数,避免死循环不方便查找错误,如果递归超过20层,报错不在递归下去</summary>
- private int recursiveCount = 0;
- /// <summary>下载依赖的包</summary>
- private bool LoadDepAssets(CAssetsConfigInfo assetsConfigInfo, CAssetsConfigInfo debugInfo)
- {
- //增加递归次数
- recursiveCount++;
- //如果递归超过20层,报错不在递归下去
- if(recursiveCount>20)
- {
- #if UNITY_EDITOR
- CDebug.LogError("包的依赖关系层次超过20层 name=" + debugInfo.assetsName);
- #endif
- return false;
- }
- //依赖项依赖的资源 循环递归,如果存在循环依赖关系这里会死循环
- if(assetsConfigInfo==null)
- {
- CDebug.Log("assetsConfigInfo==null");
- return false;
- }
- int depCount = assetsConfigInfo.AssetsDepInfoList.Count;
- for (int i = 0; i < depCount; i++)
- {
- //递归下载
- LoadDepAssets(assetsConfigInfo.AssetsDepInfoList[i], debugInfo);
- }
- //添加到需要的下载的队列
- bool isDataComplete = this.AddNeedLoadAssets(assetsConfigInfo.assetsName);
- //减少递归次数
- recursiveCount--;
- return isDataComplete;
- }
- /// <summary>添加需要下载的资源</summary>
- private bool AddNeedLoadAssets(string needAssets)
- {
- //是否已经下载完毕
- CAssetsInfo assetsInfo = this.GetAssets(needAssets);
- if (assetsInfo!=null)
- {
- waitLoadDataList[0].UpdateProgress(assetsInfo.assetsName, 100);
- return waitLoadDataList[0].ChectLoadComplete(assetsInfo);
- }
- //是否已经在队列中
- if (waitNeedLoadAssets.IndexOf(needAssets)!=-1)
- {
- return false;
- }
- //是否在下载中
- for (int i = 0; i < CLoaderConst.CLoaderMaxCount; i++)
- {
- if (!catchLoaderList[i].IsLoadIng)
- { continue; }
-
- if(catchLoaderList[i].assetsName == needAssets)
- {
- return false;
- }
- }
- //添加队列
- waitNeedLoadAssets.Add(needAssets);
- //检查是否有空闲的loader,如果有下载队列中的资源
- if(waitNeedLoadAssets.Count==1)
- {
- this.CheckStartLoad();
- }
- return false;
- }
- /// <summary>检查是否可以开始下载资源</summary>
- private void CheckStartLoad()
- {
- //没有需要下载的资源了
- if (waitNeedLoadAssets.Count == 0)
- {
- return;
- }
- string assetsName = "";
- for (int i = 0; i < CLoaderConst.CLoaderMaxCount; i++)
- {
- if (catchLoaderList[i].IsLoadIng)
- { continue; }
- //真正的开始下载 下载进度和是否下载完成全都在update函数中检查
- assetsName = waitNeedLoadAssets[0];
- waitNeedLoadAssets.RemoveAt(0);
- loadIngLoaderCount++;
- catchLoaderList[i].StartLoad(CLoaderConst.AssetsBundleURL + assetsName, assetsName);
- //没有需要下载的资源了
- if(waitNeedLoadAssets.Count==0)
- {
- break;
- }
- }
- }
- /// <summary>帧频函数</summary>
- private void Update()
- {
- //检查场景加载
- CheckSceneAsync();
- //没有资源在下载不需要检查
- if(loadIngLoaderCount==0)
- { return; }
- //整个的loaderdata是否下载完毕,第一层队列是否下载完毕
- bool isDataComplete = false;
- //第二层队列是否有loader下载完毕
- bool isBeLoadComplete = false;
- CLoaderData loaderData = waitLoadDataList[0];
- CLoaderAB loader = null;
- for (int i = 0; i < CLoaderConst.CLoaderMaxCount; i++)
- {
- loader = catchLoaderList[i];
- if (!loader.IsLoadIng)
- { continue; }
- loader.OnUpdate();
- //下载完成
- if(loader.IsLoadComplete)
- {
- //让资源入库
- this.AddAssets(loader);
- //检查DataLoader整体是否下载完毕
- isDataComplete = loaderData.ChectLoadComplete(this.GetAssets(loader.assetsName));
- //重置loader对象
- loader.Reset();
- //标记有loader空闲了
- isBeLoadComplete = true;
- //修改使用中的loader个数
- loadIngLoaderCount--;
- //资源下载完毕 跳出循环 执行回调和下一个LoaderData
- if (isDataComplete)
- {
- break;
- }
- }
- else
- {
- loaderData.UpdateProgress(loader.assetsName, loader.LoadProgress);
- }
- }
- //执行回调和下一个LoaderData
- if(isDataComplete)
- {
- OnFirstLoaderComplete();
- }
- //第二层队列是否有loader下载完毕
- else if (isBeLoadComplete)
- {
- this.CheckStartLoad();
- }
- }
- /// <summary>LoadData下载完毕</summary>
- private void OnFirstLoaderComplete()
- {
- CLoaderData loaderData = waitLoadDataList[0];
- //从队列中删除第一个资源
- waitLoadDataList.RemoveAt(0);
- //执行回调
- loaderData.OnCompleteCallBack();
- //继续下载
- this.LoadFistLoaderData();
- }
- /// <summary>场景加载对象</summary>
- private AsyncOperation mSceneAsync = null;
- /// <summary>加载完成回调</summary>
- private OnDelegateLoadSceneComplete OnLoadSceneComplete;
- /// <summary>当前场景名称</summary>
- private string strCurSceneName = "";
- /// <summary>当前场景名称</summary>
- public string CurSceneName
- {
- get { return strCurSceneName; }
- }
- private string strLoadingSceneName = "";
- /// <summary>加载场景</summary>
- public void LoadScene(string sceneName, OnDelegateLoadSceneComplete onLoadSceneComplete)
- {
- //当前场景就是需要加载的场景
- if (sceneName == strCurSceneName)
- {
- if (onLoadSceneComplete != null)
- {
- onLoadSceneComplete();
- }
- return;
- }
- //正在加载其他场景
- if (mSceneAsync!=null)
- {
- CDebug.LogError("重复调用加载场景逻辑!");
- return;
- }
- OnLoadSceneComplete = onLoadSceneComplete;
- strLoadingSceneName = sceneName;
- mSceneAsync = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync (sceneName);
- }
- /// <summary>检查异步加载场景是否完成</summary>
- private void CheckSceneAsync()
- {
- //如果刚刚加载完成,等待一帧在返回true
- if (mSceneAsync != null && mSceneAsync.isDone)
- {
- mSceneAsync = null;
- strCurSceneName = strLoadingSceneName;
- if (OnLoadSceneComplete != null)
- {
- OnDelegateLoadSceneComplete onCallBack = OnLoadSceneComplete;
- OnLoadSceneComplete = null;
- onCallBack();
- onCallBack = null;
- }
- }
- }
- }
- }
|