//根据路径卸载资源 public void UnloadAsset(string path, bool destroyObj = false) { if (string.IsNullOrEmpty(path)) { return; } uint crc = CrcHelper.StringToCRC32(path); ResourceItem item = null; if (!AssetCacheDict.TryGetValue(crc, out item) || item == null) { return; } if (item == null) { return; } item.RefCount--; DestroyResourceItem(item, destroyObj); }
//异步加载资源, 仅仅是不需要实例化的资源,音频,图片等 public void AsyncLoadAsset <T>(string path, OnAsyncResourceObjFinished dealFinished, LoadAssetPriority priority, object param1 = null, object param2 = null, object param3 = null, uint crc = 0) where T : UnityEngine.Object { if (crc == 0) { crc = CrcHelper.StringToCRC32(path); } ResourceItem item = GetAssetFromAssetCache(crc); if (item != null) { if (dealFinished != null) { dealFinished(path, item.Obj, param1, param2, param3); } return; } //判断是否在加载中 AsyncLoadAssetParam para = null; if (!m_loadingAssetDict.TryGetValue(crc, out para) || para == null) { para = m_asyncLoadAssetParamPool.Spawn(true); para.m_crc = crc; para.m_path = path; para.m_priority = priority; //这里应该还少了对Sprite的判定 m_loadingAssetDict.Add(crc, para); m_loadingAssetList[(int)priority].Add(para); } AsyncCallBack callback = m_asyncCallBackPool.Spawn(true); callback.m_resourceObjDealFinished = dealFinished; callback.m_param1 = param1; callback.m_param2 = param2; callback.m_param3 = param3; para.m_callbackList.Add(callback); }
//读取资源依赖文件, 初始化所有资源都一一对应的ResourceItem类对象 public bool LoadAssetBundleConfig() { m_resourceItemDict.Clear(); string configPath = ABPathConfig.DependenceFile4AssetBundle; AssetBundle configAB = AssetBundle.LoadFromFile(configPath); TextAsset textAsset = configAB.LoadAsset <TextAsset>(ABPathConfig.DependenceFileName); if (textAsset == null) { Debug.Log("AssetBundleConfig is not exists!"); return(false); } MemoryStream ms = new MemoryStream(textAsset.bytes); BinaryFormatter bf = new BinaryFormatter(); AssetBundleConfig abConfig = (AssetBundleConfig)bf.Deserialize(ms); ms.Close(); for (int i = 0; i < abConfig.ABList.Count; i++) { ResourceItem item = new ResourceItem(); ABBase abBase = abConfig.ABList[i]; item.Crc = abBase.Crc; item.AssetName = abBase.AssetName; item.ABName = abBase.ABName; item.DependABList = new List <string>(abBase.DependABList); if (m_resourceItemDict.ContainsKey(item.Crc) == false) { m_resourceItemDict.Add(item.Crc, item); } else { Debug.Log("重复的Crc, 资源名: " + item.AssetName + ", AB包名: " + item.ABName); } } return(true); }
//根据资源对象卸载资源 public void UnLoadAsset(Object obj, bool destroyObj = false) { if (obj == null) { return; } ResourceItem item = null; foreach (ResourceItem resourceItem in AssetCacheDict.Values) { if (resourceItem.Guid == obj.GetInstanceID()) { item = resourceItem; break; } } if (item == null) { return; } item.RefCount--; DestroyResourceItem(item, destroyObj); }
//根据crc获取ResourceItem, 只负责获取到资源所在AssetBundle. public ResourceItem LoadResourceItem(uint crc) { ResourceItem resourceItem = null; if (!m_resourceItemDict.TryGetValue(crc, out resourceItem) || resourceItem == null) { Debug.Log("没有找到Crc: " + crc.ToString() + "对应的资源!"); return(null); } if (resourceItem.Ab != null) { return(resourceItem); } if (resourceItem.DependABList != null) { for (int i = 0; i < resourceItem.DependABList.Count; i++) { LoadAssetBundle(resourceItem.DependABList[i]); } } resourceItem.Ab = LoadAssetBundle(resourceItem.ABName); return(resourceItem); }
//异步加载资源协程 IEnumerator AsyncLoadAssetCoroutine() { List <AsyncCallBack> callbackList = null; long lastYieldTime = System.DateTime.Now.Ticks; while (true) { bool haveYield = false; for (int i = 0; i < (int)LoadAssetPriority.NUM; i++) { List <AsyncLoadAssetParam> loadingList = m_loadingAssetList[i]; if (loadingList.Count <= 0) { continue; } //取出第一个要加载的资源参数 AsyncLoadAssetParam param = loadingList[0]; loadingList.RemoveAt(0); callbackList = param.m_callbackList; Object obj = null; ResourceItem item = null; #if UNITY_EDITOR if (!m_loadFromAssetBundle) { obj = LoadAssetByEditor <Object>(param.m_path); //模拟异步加载 yield return(new WaitForSeconds(0.5f)); item = AssetBundleManager.Instance.FindResourceItem(param.m_crc); } #endif if (obj == null) { item = AssetBundleManager.Instance.LoadResourceItem(param.m_crc); if (item != null && item.Ab != null) { AssetBundleRequest request = null; if (param.m_Sprite) //图片资源需要特殊处理,因为object不能转Sprite { request = item.Ab.LoadAssetAsync <Sprite>(item.AssetName); } else { request = item.Ab.LoadAssetAsync <Object>(item.AssetName); } yield return(request); if (request.isDone) { obj = request.asset; } lastYieldTime = System.DateTime.Now.Ticks; } } CacheAsset2AssetCache(param.m_path, ref item, param.m_crc, obj, callbackList.Count); for (int j = 0; j < callbackList.Count; j++) { AsyncCallBack callback = callbackList[j]; if (callback != null && callback.m_gameObjDealFinished != null) { GameObjectItem gameObjectItem = callback.m_gameObjectItem; gameObjectItem.ResourceItem = item; callback.m_gameObjDealFinished(param.m_path, gameObjectItem, gameObjectItem.Param1, gameObjectItem.Param2, gameObjectItem.Param3); callback.m_gameObjDealFinished = null; } if (callback != null && callback.m_resourceObjDealFinished != null) { callback.m_resourceObjDealFinished(param.m_path, obj, callback.m_param1, callback.m_param2, callback.m_param3); callback.m_resourceObjDealFinished = null; } callback.Reset(); m_asyncCallBackPool.Recycle(callback); } obj = null; callbackList.Clear(); m_loadingAssetDict.Remove(param.m_crc); param.Reset(); m_asyncLoadAssetParamPool.Recycle(param); if (System.DateTime.Now.Ticks - lastYieldTime > MAXLOADASSETTIME) { yield return(null); lastYieldTime = System.DateTime.Now.Ticks; haveYield = true; } } //下边的yield return null, 作用于没有异步加载资源请求时 if (!haveYield || System.DateTime.Now.Ticks - lastYieldTime > MAXLOADASSETTIME) { lastYieldTime = System.DateTime.Now.Ticks; yield return(null); } } }