/// <summary> /// 给ObjectsManager提供的接口,加载resGo /// </summary> public void AsyncLoadResource(string path, ResourceGameObject resGo, AsyncLoadResGoDealFinish resGoDealFinish) { uint pathCrc = Crc32.GetCRC32(path); AssetBundleDataItem dataItem = GetCacheABDataItem(pathCrc); if (dataItem != null) { resGo.ABDataItem = dataItem; if (resGoDealFinish != null) { resGoDealFinish(path, resGo, resGo.Param1, resGo.Param2, resGo.Param3); } return; } AsyncLoadDataItem asyncDataItem = null; if (!m_asyncLoadingItemDic.TryGetValue(pathCrc, out asyncDataItem) && asyncDataItem == null) { asyncDataItem = m_asyncDataItemPool.Create(true); asyncDataItem.Path = path; asyncDataItem.Crc = pathCrc; asyncDataItem.Priority = resGo.Priority; m_asyncLoadItemListArray[(int)resGo.Priority].Add(asyncDataItem); m_asyncLoadingItemDic.Add(pathCrc, asyncDataItem); } AsyncLoadCallBack callBack = m_asyncCallBackPool.Create(true); callBack.ResGoDealFinish = resGoDealFinish; callBack.resGo = resGo; asyncDataItem.CallBackList.Add(callBack); }
public bool CancelAsyncLoad(ResourceGameObject resGo) { AsyncLoadDataItem asyncDataItem = null; //判断正在加载的字典中是否包含asyncDataItem, 并且没有进入异步的for循环 if (m_asyncLoadingItemDic.TryGetValue(resGo.Crc, out asyncDataItem) && m_asyncLoadItemListArray[(int)resGo.Priority].Contains(asyncDataItem)) { //重置callbackList var callBackList = asyncDataItem.CallBackList; for (int i = callBackList.Count - 1; i >= 0; i--) { //回收回调(可能有多个回调) AsyncLoadCallBack callBack = callBackList[i]; if (callBack != null) { callBack.Reset(); callBackList.Remove(callBack); m_asyncCallBackPool.Recycle(callBack); } } if (callBackList.Count <= 0) { //只有全部回调都移除了才能真正取消异步加载 asyncDataItem.Reset(); m_asyncLoadingItemDic.Remove(resGo.Crc); m_asyncLoadItemListArray[(int)resGo.Priority].Remove(asyncDataItem); m_asyncDataItemPool.Recycle(asyncDataItem); return(true); } } return(false); }
/// <summary> /// 异步加载资源, 仅加载不需要实例化的资源, 音频,图片等 /// </summary> public void AsyncLoadResource(string path, AsyncLoadDealFinish dealFinish, AsyncLoadPriority priority, bool isSprite = false, object param1 = null, object param2 = null, object param3 = null, uint pathCrc = 0) { if (pathCrc == 0) { pathCrc = Crc32.GetCRC32(path); } //这里跟同步加载一样,缓存列表中有的话就直接取出来就行了, 然后把path,obj还有相应的参数传给回调就行了 AssetBundleDataItem dataItem = GetCacheABDataItem(pathCrc); if (dataItem != null && dataItem.Obj != null) { if (dealFinish != null) { dealFinish(path, dataItem.Obj, param1, param2, param3); } return; } //缓存列表中没有时,才进行异步加载 AsyncLoadDataItem asyncDataItem = null; if (!m_asyncLoadingItemDic.TryGetValue(pathCrc, out asyncDataItem) && asyncDataItem == null) { //初始化数据类 asyncDataItem = m_asyncDataItemPool.Create(true); asyncDataItem.Path = path; asyncDataItem.Crc = pathCrc; asyncDataItem.IsSprite = isSprite; asyncDataItem.Priority = priority; m_asyncLoadItemListArray[(int)priority].Add(asyncDataItem); //加到优先级列表数组中 m_asyncLoadingItemDic.Add(pathCrc, asyncDataItem); //加到正在加载的dic中 } //不论正在异步加载的dic(m_asyncLoadingItemDic)中有没有asyncDataItem, 都要进行回调列表的追加 AsyncLoadCallBack callBack = m_asyncCallBackPool.Create(true); callBack.DealFinish = dealFinish; callBack.Param1 = param1; callBack.Param2 = param2; callBack.Param3 = param3; asyncDataItem.CallBackList.Add(callBack); }
private IEnumerator AsyncLoadCoroutine() { long preYieldTime = System.DateTime.Now.Ticks; //上一次返回的时间点 List <AsyncLoadCallBack> callBackList = null; while (true) { bool hadYield = false; for (int i = 0; i < (int)AsyncLoadPriority.Num; i++) //每次循环都是从最高优先级开始的(0) { List <AsyncLoadDataItem> asyncDataItemList = m_asyncLoadItemListArray[i]; if (asyncDataItemList == null || asyncDataItemList.Count <= 0) { continue; } if (m_asyncLoadItemListArray[(int)AsyncLoadPriority.High].Count > 0) { i = (int)AsyncLoadPriority.High; } else if (m_asyncLoadItemListArray[(int)AsyncLoadPriority.Middile].Count > 0) { i = (int)AsyncLoadPriority.Middile; } AsyncLoadDataItem asyncDataItem = asyncDataItemList[0]; asyncDataItemList.Remove(asyncDataItem); Object obj = null; AssetBundleDataItem dataItem = null; #if UNITY_EDITOR if (!GameRoot.m_UseAssetBundleInEditor) { if (asyncDataItem.IsSprite) { obj = LoadABDataItemInEditorMode <Sprite>(asyncDataItem.Path); } else { obj = LoadABDataItemInEditorMode <Object>(asyncDataItem.Path); } //模拟异步加载 yield return(new WaitForSeconds(0.5f)); dataItem = AssetBundleManager.Instance.GetABDataItem(asyncDataItem.Crc); } #endif if (obj == null) { dataItem = AssetBundleManager.Instance.LoadABDataItem(asyncDataItem.Crc); AssetBundleRequest abRequest = null; if (asyncDataItem.IsSprite) { abRequest = dataItem.AB.LoadAssetAsync <Sprite>(dataItem.AssetName); } else { abRequest = dataItem.AB.LoadAssetAsync(dataItem.AssetName); } yield return(abRequest); if (abRequest.isDone) { obj = abRequest.asset; } yield return(obj); preYieldTime = System.DateTime.Now.Ticks; } callBackList = asyncDataItem.CallBackList; //缓存dataitem CacheABDataItem(asyncDataItem.Path, ref dataItem, obj, callBackList.Count); //执行回调列表 for (int j = 0; j < callBackList.Count; j++) { AsyncLoadCallBack callBack = null; callBack = callBackList[j]; if (callBack != null) { //不需要实例化资源的异步加载回调 if (callBack.DealFinish != null) { callBack.DealFinish(asyncDataItem.Path, obj, callBack.Param1, callBack.Param2, callBack.Param3); callBack.DealFinish = null; } //实例化对象异步加载回调 if (callBack.ResGoDealFinish != null && callBack.resGo != null) { //执行这个回调会赋值resGo的abDataItem,(因为在协程里面才是加载dataItem的) ResourceGameObject resGo = callBack.resGo; resGo.ABDataItem = dataItem; callBack.ResGoDealFinish(asyncDataItem.Path, resGo, resGo.Param1, resGo.Param2, resGo.Param3); callBack.ResGoDealFinish = null; resGo = null; } callBack.Reset(); //重置 m_asyncCallBackPool.Recycle(callBack); //回收类对象 } } //清理,回收 asyncDataItem.Reset(); //重置 m_asyncLoadingItemDic.Remove(asyncDataItem.Crc); //从正在加载dic中移除 m_asyncDataItemPool.Recycle(asyncDataItem); //回收类对象 obj = null; callBackList.Clear(); if (System.DateTime.Now.Ticks - preYieldTime > MAXASYNCLOADTIME) { hadYield = true; //等待一帧 yield return(null); preYieldTime = System.DateTime.Now.Ticks; } } if (!hadYield && System.DateTime.Now.Ticks - preYieldTime > MAXASYNCLOADTIME) { preYieldTime = System.DateTime.Now.Ticks; yield return(null); } } }