//异步 #region Load Asynchronize /// <summary> /// 异步加载bundle /// </summary> /// <param name="packInfo">bundle打包信息</param> /// <param name="complete">加载完成回调</param> /// <param name="failure">加载失败回调</param> /// <param name="loading">加载进度回调</param> /// <returns></returns> public IEnumerator LoadAsync(BundlePackInfo packInfo, BundleLoadedDelegate complete, BundleLoadFailedDelegate failure, BundleLoadingDelegate loading = null) { if (packInfo == null) { JW.Common.Log.LogE("Async loading bundle with null pack info."); yield break; } //判断是否已经加载 BundleRef br = null; if (_bundleDict.TryGetValue(packInfo.Path, out br)) { br.RefCnt++; if (_unloadingBundle.ContainsKey(packInfo.Path)) { _unloadingBundle.Remove(packInfo.Path); } if (loading != null) { loading(packInfo, 1f); } if (complete != null) { complete(br); } yield break; } // 正在加载 if (_loadingBundle.Contains(packInfo.Path)) { yield return(null); while (_loadingBundle.Contains(packInfo.Path)) { yield return(null); } if (_bundleDict.TryGetValue(packInfo.Path, out br)) { br.RefCnt++; if (complete != null) { complete(br); } } yield break; } //LoadFormFile 同步加载 if (packInfo.HasFlag(EBundleFlag.UnCompress) || packInfo.HasFlag(EBundleFlag.LZ4)) { LoadSync(packInfo); yield break; } //LZMA _loadingBundle.Add(packInfo.Path); // 依赖 for (int i = 0; packInfo.Dependencies != null && i < packInfo.Dependencies.Count; i++) { yield return(StartCoroutine(LoadAsync(packInfo.Dependencies[i], null, null))); } // 内部含有 if (packInfo.IsNoBundle() && !packInfo.Outside) { _loadingBundle.Remove(packInfo.Path); if (failure != null) { failure(packInfo, ""); } yield break; } { //对于LZMA AssetBundle.LoadFromFileAsync 会占用解压内存 //手册说用UnityWebRequest 可以首次解压 后缓存,但对于本地的包又说用AssetBundle.LoadFromFileAsync string path = GetBundleFullPath(packInfo, false); JW.Common.Log.LogD("Async load bundle path:{0}", path); AssetBundleCreateRequest www = AssetBundle.LoadFromFileAsync(path); float progress = 0.0f; while (!www.isDone) { if (loading != null) { if (www.progress < 0.00001 && www.progress > -0.00001) { progress += 0.01f; loading(packInfo, progress); } else { loading(packInfo, www.progress); } } yield return(null); } _loadingBundle.Remove(packInfo.Path); // failed if (www.assetBundle == null) { JW.Common.Log.LogE("Async loading bundle {0} failed, error:{1}", path, ""); if (failure != null) { failure(packInfo, ""); } www = null; yield break; } if (loading != null) { loading(packInfo, 1f); } // succeed if (www.assetBundle != null) { br = new BundleRef(packInfo); br.Bundle = www.assetBundle; _bundleDict.Add(packInfo.Path, br); if (complete != null) { complete(br); } } www = null; } /*Test2 * { * string path = GetBundleFullPath(packInfo, true); * JW.Common.Log.LogD("Async load bundle use UnityWebRequest path:{0}", path); * UnityWebRequest www = UnityWebRequest.GetAssetBundle(path); * yield return www.SendWebRequest(); * float progress = 0.0f; * while (!www.isDone) * { * if (loading != null) * { * if (www.downloadProgress < 0.00001 && www.downloadProgress > -0.00001) * { * progress += 0.01f; * loading(packInfo, progress); * } * else * { * loading(packInfo, www.downloadProgress); * } * } * yield return null; * } * * _loadingBundle.Remove(packInfo.Path); * // failed * AssetBundle ab = DownloadHandlerAssetBundle.GetContent(www); * if (ab == null) * { * JW.Common.Log.LogE("Async loading bundle use UnityWebRequest {0} failed, error:{1}", path, ""); * if (failure != null) * { * failure(packInfo, ""); * } * www.Dispose(); * www = null; * yield break; * } * * if (loading != null) * { * loading(packInfo, 1f); * } * * // succeed * if (ab != null) * { * br = new BundleRef(packInfo); * br.Bundle = ab; * _bundleDict.Add(packInfo.Path, br); * * if (complete != null) * { * complete(br); * } * } * www.Dispose(); * www = null; * }*/ }
/// <summary> /// 异步加载bundle列表 /// </summary> /// <param name="packInfo">bundle打包信息</param> /// <param name="complete">加载完成回调</param> /// <param name="failure">加载失败回调</param> /// <param name="loading">加载进度回调</param> /// <returns></returns> public IEnumerator LoadAsync(JWObjList <BundlePackInfo> packInfos, BundleLoadedDelegate complete, BundleLoadFailedDelegate failure, BundleLoadingDelegate loading = null) { if (packInfos == null) { JW.Common.Log.LogE("Async loading bundle with null pack info."); yield break; } //JWObjList<BundleRef> bundleRefs = new JWObjList<BundleRef>(); for (int i = 0; i < packInfos.Count; ++i) { BundlePackInfo packInfo = packInfos[i]; if (packInfo != null) { // ab has been loaded BundleRef br = null; if (_bundleDict.TryGetValue(packInfo.Path, out br)) { br.RefCnt++; if (_unloadingBundle.ContainsKey(packInfo.Path)) { _unloadingBundle.Remove(packInfo.Path); } if (loading != null) { loading(packInfo, 1f); } if (complete != null) { complete(br); } continue; } // loading if (_loadingBundle.Contains(packInfo.Path)) { yield return(null); while (_loadingBundle.Contains(packInfo.Path)) { yield return(null); } if (_bundleDict.TryGetValue(packInfo.Path, out br)) { br.RefCnt++; if (complete != null) { complete(br); } } continue; } if (packInfo.HasFlag(EBundleFlag.UnCompress) || packInfo.HasFlag(EBundleFlag.LZ4)) { LoadSync(packInfo); yield break; } //LZMA // 放在加载依赖前,因为加载依赖表示已经开始加载了 _loadingBundle.Add(packInfo.Path); // dependency for (int j = 0; packInfo.Dependencies != null && j < packInfo.Dependencies.Count; j++) { yield return(StartCoroutine(LoadAsync(packInfo.Dependencies[j], null, null))); } // no bundle if (packInfo.IsNoBundle() && !packInfo.Outside) { _loadingBundle.Remove(packInfo.Path); yield break; } // load string path = GetBundleFullPath(packInfo, true); JW.Common.Log.LogD("Async load bundle liat path:{0}", path); UnityWebRequest www = null; www = UnityWebRequest.GetAssetBundle(path); yield return(www.SendWebRequest()); // loading progress if (loading != null) { float progress = 0.0f; while (string.IsNullOrEmpty(www.error) && !www.isDone) { if (www.downloadProgress < 0.00001 && www.downloadProgress > -0.00001) { progress += 0.01f; loading(packInfo, progress); } else { loading(packInfo, www.downloadProgress); } yield return(null); } if (string.IsNullOrEmpty(www.error)) { loading(packInfo, 1f); } } _loadingBundle.Remove(packInfo.Path); // failed if (!string.IsNullOrEmpty(www.error)) { JW.Common.Log.LogE("Async loading bundle {0} failed, error:{1}", packInfo.Path, www.error); if (failure != null) { failure(packInfo, www.error); } www.Dispose(); continue; } AssetBundle ab = DownloadHandlerAssetBundle.GetContent(www); // succeed if (ab != null) { br = new BundleRef(packInfo); br.Bundle = ab; _bundleDict.Add(packInfo.Path, br); if (complete != null) { complete(br); } } www.Dispose(); } } }
/// <summary> /// 同步加载bundle /// </summary> /// <param name="packInfo">bundle打包信息</param> public void LoadSync(BundlePackInfo packInfo) { if (packInfo == null) { JW.Common.Log.LogE("Sync loading bundle with null pack info."); return; } //是否已经加载 BundleRef br = null; if (_bundleDict.TryGetValue(packInfo.Path, out br)) { br.RefCnt++; if (_unloadingBundle.ContainsKey(packInfo.Path)) { _unloadingBundle.Remove(packInfo.Path); } return; } // 是否正在加载 if (_loadingBundle.Contains(packInfo.Path)) { JW.Common.Log.LogE("Bundle is loading when load sync. bundle:{0}", packInfo.Path); return; } // 依赖 for (int i = 0; packInfo.Dependencies != null && i < packInfo.Dependencies.Count; i++) { LoadSync(packInfo.Dependencies[i]); } //干活 AssetBundle ab = null; string path = GetBundleFullPath(packInfo, false); JW.Common.Log.LogD("Sync load bundle path:{0}", path); // if (packInfo.HasFlag(EBundleFlag.UnCompress) || packInfo.HasFlag(EBundleFlag.LZ4)) { ab = AssetBundle.LoadFromFile(path); } else { //LZMA 压缩的AssetBundle //LZMA压缩的 u2017可以直接通过 LoadFromFile 创建支持StreamingAssetPath 内存占用大 ab = AssetBundle.LoadFromFile(path); /* * byte[] bytes = null; * //优先外围目录 * if (FileUtil.IsExistInIFSExtraFolder(packInfo.Path)) * { * bytes = File.ReadAllBytes(path); * } * else * { * * //StreamingAsset目录的 #if UNITY_ANDROID && !UNITY_EDITOR * bytes = NativeHelper.Android_ReadFileInAssets(packInfo.Path); #else * bytes = File.ReadAllBytes(path); #endif * } * * if (null != bytes) * { * //注意 * //https://unity3d.com/cn/learn/tutorials/topics/best-practices/assetbundle-fundamentals?playlist=30089 * //The peak amount of memory consumed by this API will be at least twice the size of the AssetBundle: * ab = AssetBundle.LoadFromMemory(bytes); * }*/ } // 完成 if (ab != null) { br = new BundleRef(packInfo); br.Bundle = ab; _bundleDict.Add(packInfo.Path, br); } }