private static void RetainBundleInternal(LoadedBundle bundle, int count) { #if UNITY_EDITOR if (s_BundleDirectUseCount.ContainsKey(bundle.Name)) { s_BundleDirectUseCount[bundle.Name] += count; } else { s_BundleDirectUseCount.Add(bundle.Name, count); } #endif for (int i = 0; i < bundle.Dependencies.Count; i++) { var refBundleName = bundle.Dependencies[i]; if (!s_BundleRefCounts.ContainsKey(refBundleName)) { s_BundleRefCounts[refBundleName] = count; } else { s_BundleRefCounts[refBundleName] += count; } } }
// Load bản thân bundle dựa theo tham số là tên public static bool LoadBundleInternal(string bundleName) { LoadedBundle bundle = null; // Xem trong từ điển đã có chưa loadedBundles.TryGetValue(bundleName, out bundle); if (bundle != null) { // Nếu có rồi thì tăng biến số lượng tham chiếu và trả về true bundle.mRefCount++; return(true); } // Nếu vẫn còn đang download cũng tả về true if (downloadingWWWs.ContainsKey(bundleName)) { return(true); } // Nếu chưa có trong từ điển và cũng chưa trong download thì bắt đầu download về hoặc load từ bộ nhớ cache (nếu có) WWW download = WWW.LoadFromCacheOrDownload(baseURL + bundleName, manifest.GetAssetBundleHash(bundleName)); // Sau đó add vào danh sách đang download và trả về false downloadingWWWs.Add(bundleName, download); return(false); }
private static void AsyncAssetLoaded(AssetBundleRequest request, LoadedBundle loadedBundle) { if (request.asset != null) { TrackObjectInternal(request.asset, loadedBundle); } }
public override bool Update() { if (m_Request != null) { return(false); } LoadedBundle bundle = BundleManager.GetLoadedBundle(m_AssetBundleName, out m_DownloadingError); if (bundle != null) { if (m_IsAdditive) { m_Request = Application.LoadLevelAdditiveAsync(m_LevelName); } else { m_Request = Application.LoadLevelAsync(m_LevelName); } return(false); } else { return(true); } }
private static void TrackIndepenantInternal(LoadedBundle loadedBundle, GameObject go) { if (go.scene.name == null) { throw new System.Exception("GameObject is not instantiated one"); } s_TrackingGameObjects.Add(new TrackingGameObject(go, loadedBundle)); RetainBundleInternal(loadedBundle, 1); }
static void CollectSceneNames(LoadedBundle loadedBundle) { var scenes = loadedBundle.Bundle.GetAllScenePaths(); foreach (var scene in scenes) { s_SceneNames[scene] = loadedBundle; } }
private static void AsyncAssetLoaded(AssetBundleRequest request, LoadedBundle loadedBundle) { if (request.asset != null) { TrackObjectInternal(request.asset, loadedBundle); } //because we did increase ref count in loadasync function, it need to be released ReleaseBundleInternal(loadedBundle, 1); }
static IEnumerator ReloadBundle(string bundleName, LoadedBundle loadedBundle) { if (LogMessages) { Debug.Log($"Start Reloading Bundle {bundleName}"); } var bundleReq = loadedBundle.IsLocalBundle? UnityWebRequestAssetBundle.GetAssetBundle(loadedBundle.LoadPath) : UnityWebRequestAssetBundle.GetAssetBundle(loadedBundle.LoadPath, new CachedAssetBundle(bundleName, loadedBundle.Hash)); loadedBundle.IsReloading = true; yield return(bundleReq.SendWebRequest()); loadedBundle.IsReloading = false; if (bundleReq.isNetworkError || bundleReq.isHttpError) { Debug.LogError($"Bundle reload error { bundleReq.error }"); yield break; } if (!s_AssetBundles.TryGetValue(bundleName, out var currentLoadedBundle) || currentLoadedBundle.Hash != loadedBundle.Hash) { if (LogMessages) { Debug.Log("Bundle To Reload does not exist(changed during loaing)"); } bundleReq.Dispose(); yield break; } //if we can swap now if (!s_BundleRefCounts.TryGetValue(bundleName, out var refCount) || refCount == 0) { if (LogMessages) { Debug.Log($"Reloaded Bundle {bundleName}"); } loadedBundle.Bundle.Unload(true); loadedBundle.Bundle = DownloadHandlerAssetBundle.GetContent(bundleReq); bundleReq.Dispose(); } else { if (LogMessages) { Debug.Log($"Reloaded Bundle Cached for later use {bundleName}"); } //store request for laster use loadedBundle.RequestForReload = bundleReq; } }
/// <summary> /// 手动从Bundle中加载资源唯一入口 /// </summary> /// <param name="path"></param> /// <param name="name"></param> /// <param name="type"></param> /// <param name="onLoaded"></param> /// <param name="async"></param> private void LoadAssetFromBundle(string path, string assetName, System.Type type, LoadedCallback onLoaded, bool async, AssetType assetType = AssetType.GameObject) { if (AppConst.UseAssetBundle) { Util.Log(string.Format("LoadAssetFromBundle, bundle:{0}, asset:{1}", path, assetName)); LoadAssetBundle(path, (data) => { LoadedBundle abCache = data as LoadedBundle; object asset = null; if (abCache != null) { string abName = FileHelper.CheckBundleName(path); var cache = LoadedBundleCtrl.Instance.UnReferenceLoadedBundle(abName); if (cache != null && 0 == cache.ReferencedCount) { cache.ReferencedCount = 1; if (!m_handLoad.Contains(abName)) { m_handLoad.Add(abName); } } if (!string.IsNullOrEmpty(assetName)) { asset = abCache.LoadAsset(assetName, type); if (type != null && type == typeof(GameObject)) { abCache.UnloadSelf(); } } else { asset = abCache.Bundle; } } if (asset == null) { Util.LogError(string.Format("LoadAssetFromBundle, path:{0},name:{1}, asset is null", path, assetName)); } if (onLoaded != null) { onLoaded(asset); } }, async); } else { LoadAsset(path, onLoaded, type, false, assetType); } }
/// <summary> /// 引用包 /// </summary> /// <param name="abName"></param> /// <returns></returns> public LoadedBundle ReferenceLoadedBundle(string abName) { LoadedBundle cache = null; m_loadedBundles.TryGetValue(abName, out cache); if (cache != null) { ++cache.ReferencedCount; } return(cache); }
// 加载资源清单 void LoadManifest(ManifestType mType) { if (m_manifests.ContainsKey(mType) && m_manifests[mType] != null) { DestroyImmediate(m_manifests[mType], true); m_manifests.Remove(mType); } string manifestName = mType.ToString(); Util.Log("LoadManifest manifestName " + manifestName); m_manifestNames.Add(manifestName); string strFullPath = FileHelper.SearchFilePath(GetManifestType(manifestName).ToString(), manifestName); Util.Log("strFullPath: " + strFullPath); BundleLoader bLoader = LoaderPool.Instance.GetLoader <BundleLoader>(); bLoader.Init(strFullPath, manifestName, delegate(object data) { LoadedBundle ab = data as LoadedBundle; if (ab != null) { m_manifests[mType] = ab.LoadAsset <AssetBundleManifest>("AssetBundleManifest"); m_bundleHeads[mType] = mType.ToString().ToLower().Split('_')[0]; Util.Log("manifest ab in not null over----"); } else { Util.LogError("manifest ab is null---------"); } LoadedBundleCtrl.Instance.UnReferenceLoadedBundle(manifestName); // 不走统一接口是因为manifest文件没有后缀 LoadedBundleCtrl.Instance.HandRemoveBundle(manifestName); if (m_manifests[mType] != null) { string[] bundles = m_manifests[mType].GetAllAssetBundles(); for (int i = 0; i < bundles.Length; ++i) { if (m_bundleNames.Contains(bundles[i])) { Util.LogError(string.Format("别的清单已同名的包名,{0} {1}", manifestName, bundles[i])); } m_bundleNames.Add(bundles[i]); } } }, false, null, true); }
public TrackingObject(Object obj, LoadedBundle loadedBundle) { if (s_WeakRefPool.Count > 0) { WeakRef = s_WeakRefPool.Pop(); WeakRef.Target = obj; } else { WeakRef = new System.WeakReference(obj); } Bundle = loadedBundle; RefCount = 1; }
/// <summary> /// 真正从内存卸载包(已判定不是常驻的并且为引用) /// </summary> /// <param name="abName"></param> private void RemoveLoadedBundle(string abName) { LoadedBundle cache = null; m_loadedBundles.TryGetValue(abName, out cache); if (cache != null) { cache.Unload(); m_loadedBundles.Remove(abName); } else { Util.LogWarning(string.Format("移除加载完的包失败,不存在该包:{0}", abName)); } }
private static void TrackObjectInternal(Object obj, LoadedBundle loadedBundle) { var id = obj.GetInstanceID(); if (s_TrackingObjects.TryGetValue(id, out var trackingObject)) { trackingObject.RefCount++; } else { trackingObject = new TrackingObject(obj, loadedBundle); RetainBundleInternal(trackingObject.Bundle, 1); } s_TrackingObjects[id] = trackingObject; //update }
// Get những bundle đã load xong public static LoadedBundle GetLoadedBundle(string bundleName, out string error) { // Nếu xảy ra lỗi trong quá trình download thì trả về null if (downloadingErrors.TryGetValue(bundleName, out error)) { return(null); } // Nếu bundle cần load chưa được tải về thì trả về null LoadedBundle bundle = null; loadedBundles.TryGetValue(bundleName, out bundle); if (bundle == null) { return(null); } // Nếu không phụ thuộc vào các bundle khác thì trả về string[] dependencies = null; if (!mDependencies.TryGetValue(bundleName, out dependencies)) { return(bundle); } else { // Với mỗi sự phụ thuộc foreach (string dependency in dependencies) { // Nếu bundle mà phụ thuộc vào có lỗi thì trả về luôn if (downloadingErrors.TryGetValue(dependency, out error)) { return(bundle); } // Nếu bundle mà phụ thuộc vào chưa được tải xong thì trả về null LoadedBundle dependBundle = null; loadedBundles.TryGetValue(dependency, out dependBundle); if (loadedBundles == null) { return(null); } } } return(bundle); }
private static void ReleaseBundleInternal(LoadedBundle bundle, int count) { #if UNITY_EDITOR s_BundleDirectUseCount[bundle.Name] -= count; #endif for (int i = 0; i < bundle.Dependencies.Count; i++) { var refBundleName = bundle.Dependencies[i]; if (s_BundleRefCounts.ContainsKey(refBundleName)) { s_BundleRefCounts[refBundleName] -= count; if (s_BundleRefCounts[refBundleName] <= 0) { ReloadBundle(refBundleName); } } } }
/// <summary> /// 记录加载完包 /// </summary> /// <param name="abName"></param> /// <param name="bundle"></param> /// <param name="refCount"></param> /// <returns></returns> public LoadedBundle AddLoadedBundle(string abName, AssetBundle bundle, int refCount) { if (m_loadedBundles.ContainsKey(abName)) { Util.LogWarning(string.Format("已经有同名的资源包加载完了: {0},不应该出现该情况,将被新的覆盖", abName)); } LoadedBundle cache = new LoadedBundle(abName, bundle, refCount); m_loadedBundles[abName] = cache; if (m_persistentBundles.Contains(abName)) { cache.Persistent = true; } return(cache); }
// Unload bản thân bundle public static void UnloadBundleInternal(string bundleName) { // Nếu bundle không có trong từ điển thì không cần unload string error; LoadedBundle bundle = GetLoadedBundle(bundleName, out error); if (bundle == null) { return; } // Giảm số lượng tham chiếu xuống // Nếu = 0 tức là hoàn toàn không cần bundle này nữa nên sẽ unload và xóa khỏi từ điển if (--bundle.mRefCount == 0) { bundle.mBundle.Unload(false); loadedBundles.Remove(bundleName); } }
/// <summary> /// 返回不为null 说明 包还没从内存清理(可能未被引用但是清理缓存时间还没到) /// </summary> /// <param name="abName"></param> /// <returns></returns> public LoadedBundle UnReferenceLoadedBundle(string abName) { LoadedBundle cache = null; if (!m_loadedBundles.TryGetValue(abName, out cache)) { Util.LogWarning("卸载包失败,不存在该包: " + abName); return(null); } --cache.ReferencedCount; if ((AppConst.AssetCacheTime == 0) && cache.IsCanRemove) //无缓存时间的直接删 { RemoveLoadedBundle(abName); return(null); } return(cache); }
public override bool Update() { if (request != null) { return(false); } LoadedBundle bundle = BundleManager.GetLoadedBundle(mBundleName, out mError); if (bundle != null) { request = bundle.mBundle.LoadAssetAsync(mAssetName, mType); return(false); } else { return(true); } }
public BundleLoader.BundleState LoadAssetBundle(string path, LoadedCallback onLoaded, bool async = true, BundleLoader parent = null) { string abName = FileHelper.CheckBundleName(path); if (!ManifestHasBundleInfo(abName)) { if (onLoaded != null) { onLoaded(null); } return(BundleLoader.BundleState.NotExist); } LoadedBundle loadedCache = LoadedBundleCtrl.Instance.ReferenceLoadedBundle(abName); if (loadedCache != null) { if (onLoaded != null) { onLoaded(loadedCache); } return(BundleLoader.BundleState.Loaded); } BundleLoader loadingCache = BundleLoaderCtrl.Instance.GetBundleLoader(abName); if (loadingCache != null) { loadingCache.AddHandleCallBack(onLoaded); loadingCache.AddParent(parent); return(BundleLoader.BundleState.Loading); } string fullpath = FileHelper.SearchFilePath(GetManifestType(abName).ToString(), abName); //包最终加载路径 BundleLoader bLoader = LoaderPool.Instance.GetLoader <BundleLoader>(); bLoader.Init(fullpath, abName, onLoaded, async, parent); return(BundleLoader.BundleState.JustLoad); }
/// <summary> /// 定时或切换场景时(loading场景)清除无引用的AssetBundle缓存 /// </summary> /// <param name="onlyTimeout"></param> public void ClearNoneRefBundle(bool onlyTimeout) { string[] abNames = new string[m_loadedBundles.Count]; m_loadedBundles.Keys.CopyTo(abNames, 0); string abName = ""; LoadedBundle item = null; for (int i = 0; i < abNames.Length; ++i) { abName = abNames[i]; item = m_loadedBundles[abName]; // 只清除引用计数为0的 if (item.IsCanRemove && (!onlyTimeout || item.IsTimeOut)) //onlyTimeout:false不用自己缓存时间直接删除 { RemoveLoadedBundle(abName); } } abNames = null; }
/// <summary> /// 手动移除没被引用的包(等不及定时清理了:场景包等) /// </summary> /// <param name="abName"></param> public void HandRemoveBundle(string abName) { LoadedBundle cache = null; m_loadedBundles.TryGetValue(abName, out cache); if (null != cache) { if (cache.IsCanRemove) { cache.Unload(); m_loadedBundles.Remove(abName); } else { Util.LogWarning("手动移除包失败,该包还被引用中: " + abName); } } else { Util.LogWarning("移除加载完的包失败,不存在该包: " + abName); } }
//**注意代码顺序,不要随便修改流程可引发bug void OnLoaded(AssetBundle ab) { Util.Log("LoadAsset---- " + m_abName); if (null == ab) { Util.LogError("加载包失败 " + m_path); } Util.Log(string.Format("Load {0} - {1} use {2}ms", m_path, m_async, m_watch.Elapsed.Milliseconds)); OnLoadCompleted(ab); BundleLoaderCtrl.Instance.RemoveBundleLoader(m_abName); int refCount = 0; if (m_onRefLoaded != null) { refCount = m_onRefLoaded.GetInvocationList().Length; } refCount += m_parents.Count; LoadedBundle cache = null; if (null != ab) { cache = LoadedBundleCtrl.Instance.AddLoadedBundle(m_abName, ab, refCount); } if (m_onRefLoaded != null) { Util.Log("OnLoaded m_onRefLoaded call---- "); m_onRefLoaded(cache); } for (int i = 0; i < m_parents.Count; i++) { m_parents[i].ChildLoadEnd(m_abName); } m_parents.Clear(); }
private static void TrackObjectsInternal <T>(T[] objs, LoadedBundle loadedBundle) where T : Object { int retainCount = 0; for (int i = 0; i < objs.Length; i++) { var id = objs[0].GetInstanceID(); if (s_TrackingObjects.TryGetValue(id, out var trackingObject)) { trackingObject.RefCount++; } else { trackingObject = new TrackingObject(objs[0], loadedBundle); retainCount++; } s_TrackingObjects[id] = trackingObject; //update } if (retainCount > 0) { RetainBundleInternal(loadedBundle, retainCount); //do once } }
public async Task LoadBundleFromUrl(string bundleName, ObjectDatabaseAssetIndexMap objectDatabaseAssetIndexMap, string bundleUrl, bool ignoreDependencies = false) { BundleDescription bundle; using (var packStream = VirtualFileSystem.OpenStream(bundleUrl, VirtualFileMode.Open, VirtualFileAccess.Read)) { bundle = ReadBundleDescription(packStream); } // Read and resolve dependencies if (!ignoreDependencies) { foreach (var dependency in bundle.Dependencies) { await LoadBundle(dependency, objectDatabaseAssetIndexMap); } } lock (loadedBundles) { LoadedBundle loadedBundle = null; foreach (var currentBundle in loadedBundles) { if (currentBundle.BundleName == bundleName) { loadedBundle = currentBundle; break; } } if (loadedBundle == null) { loadedBundle = new LoadedBundle { BundleName = bundleName, BundleUrl = bundleUrl, Description = bundle, ReferenceCount = 1 }; loadedBundles.Add(loadedBundle); } else { loadedBundle.ReferenceCount++; } } // Read objects lock (objects) { foreach (var objectEntry in bundle.Objects) { objects[objectEntry.Key] = new ObjectLocation { Info = objectEntry.Value, BundleUrl = bundleUrl }; } } // Merge with local (asset bundles) index map assetIndexMap.Merge(bundle.Assets); // Merge with global object database map objectDatabaseAssetIndexMap.Merge(bundle.Assets); }
static IEnumerator CoDownloadAssetBundles(AssetbundleBuildManifest manifest, IEnumerable <string> subsetNames, BundleAsyncOperation <bool> result) { if (!Initialized) { Debug.LogError("Do Initialize first"); result.Done(BundleErrorCode.NotInitialized); yield break; } #if UNITY_EDITOR if (UseAssetDatabase) { result.Done(BundleErrorCode.Success); yield break; } #endif var bundlesToUnload = new HashSet <string>(s_AssetBundles.Keys); var downloadBundleList = subsetNames == null ? manifest.BundleInfos : manifest.CollectSubsetBundleInfoes(subsetNames); var bundleReplaced = false; //bundle has been replaced result.SetIndexLength(downloadBundleList.Count); for (int i = 0; i < downloadBundleList.Count; i++) { result.SetCurrentIndex(i); var bundleInfo = downloadBundleList[i]; //remove from the set so we can track bundles that should be cleared bundlesToUnload.Remove(bundleInfo.BundleName); var islocalBundle = s_LocalBundles.TryGetValue(bundleInfo.BundleName, out var localHash) && localHash == bundleInfo.Hash; var isCached = Caching.IsVersionCached(bundleInfo.AsCached); result.SetCachedBundle(isCached); var loadURL = islocalBundle ? Utility.CombinePath(LocalURL, bundleInfo.BundleName) : Utility.CombinePath(RemoteURL, bundleInfo.BundleName); if (LogMessages) { Debug.Log($"Loading Bundle Name : {bundleInfo.BundleName}, loadURL {loadURL}, isLocalBundle : {islocalBundle}, isCached {isCached}"); } LoadedBundle previousBundle; if (s_AssetBundles.TryGetValue(bundleInfo.BundleName, out previousBundle) && previousBundle.Hash == bundleInfo.Hash) { if (LogMessages) { Debug.Log($"Loading Bundle Name : {bundleInfo.BundleName} Complete - load skipped"); } } else { var bundleReq = islocalBundle ? UnityWebRequestAssetBundle.GetAssetBundle(loadURL) : UnityWebRequestAssetBundle.GetAssetBundle(loadURL, bundleInfo.AsCached); var operation = bundleReq.SendWebRequest(); while (!bundleReq.isDone) { result.SetProgress(operation.progress); yield return(null); } if (bundleReq.isNetworkError || bundleReq.isHttpError) { result.Done(BundleErrorCode.NetworkError); yield break; } if (s_AssetBundles.TryGetValue(bundleInfo.BundleName, out previousBundle)) { bundleReplaced = true; previousBundle.Bundle.Unload(false); if (previousBundle.RequestForReload != null) { previousBundle.RequestForReload.Dispose(); //dispose reload bundle } s_AssetBundles.Remove(bundleInfo.BundleName); } var loadedBundle = new LoadedBundle(bundleInfo, loadURL, DownloadHandlerAssetBundle.GetContent(bundleReq), islocalBundle); s_AssetBundles.Add(bundleInfo.BundleName, loadedBundle); CollectSceneNames(loadedBundle); if (LogMessages) { Debug.Log($"Loading Bundle Name : {bundleInfo.BundleName} Complete"); } bundleReq.Dispose(); } } //let's drop unknown bundles loaded foreach (var name in bundlesToUnload) { var bundleInfo = s_AssetBundles[name]; bundleInfo.Bundle.Unload(false); if (bundleInfo.RequestForReload != null) { bundleInfo.RequestForReload.Dispose(); //dispose reload bundle } s_AssetBundles.Remove(bundleInfo.Name); } //bump entire bundles' usage timestamp //we use manifest directly to find out entire list for (int i = 0; i < manifest.BundleInfos.Count; i++) { var cachedInfo = manifest.BundleInfos[i].AsCached; if (Caching.IsVersionCached(cachedInfo)) { Caching.MarkAsUsed(cachedInfo); } } if (LogMessages) { Debug.Log($"CacheUsed Before Cleanup : {Caching.defaultCache.spaceOccupied} bytes"); } Caching.ClearCache(600); //as we bumped entire list right before clear, let it be just 600 if (LogMessages) { Debug.Log($"CacheUsed After CleanUp : {Caching.defaultCache.spaceOccupied} bytes"); } PlayerPrefs.SetString("CachedManifest", JsonUtility.ToJson(manifest)); GlobalBundleHash = manifest.GlobalHash.ToString(); result.Result = bundleReplaced; result.Done(BundleErrorCode.Success); }
static IEnumerator CoInitalizeLocalBundles(BundleAsyncOperation result, bool autoReloadBundle) { if (Initialized) { result.Done(BundleErrorCode.Success); yield break; } AutoReloadBundle = autoReloadBundle; if (LogMessages) { Debug.Log($"LocalURL : {LocalURL}"); } foreach (var kv in s_AssetBundles) { kv.Value.Bundle.Unload(false); } s_SceneNames.Clear(); s_AssetBundles.Clear(); s_LocalBundles.Clear(); var manifestReq = UnityWebRequest.Get(Utility.CombinePath(LocalURL, AssetbundleBuildSettings.ManifestFileName)); yield return(manifestReq.SendWebRequest()); if (manifestReq.isHttpError || manifestReq.isNetworkError) { result.Done(BundleErrorCode.NetworkError); yield break; } if (!AssetbundleBuildManifest.TryParse(manifestReq.downloadHandler.text, out var localManifest)) { result.Done(BundleErrorCode.ManifestParseError); yield break; } //cached version is recent one. var cacheIsValid = AssetbundleBuildManifest.TryParse(PlayerPrefs.GetString("CachedManifest", string.Empty), out var cachedManifest) && cachedManifest.BuildTime > localManifest.BuildTime; result.SetIndexLength(localManifest.BundleInfos.Count); for (int i = 0; i < localManifest.BundleInfos.Count; i++) { result.SetCurrentIndex(i); result.SetCachedBundle(true); AssetbundleBuildManifest.BundleInfo bundleInfoToLoad; AssetbundleBuildManifest.BundleInfo cachedBundleInfo = default; var localBundleInfo = localManifest.BundleInfos[i]; bool useLocalBundle = !cacheIsValid || //cache is not valid or... !cachedManifest.TryGetBundleInfo(localBundleInfo.BundleName, out cachedBundleInfo) || //missing bundle or... !Caching.IsVersionCached(cachedBundleInfo.AsCached); //is not cached no unusable. bundleInfoToLoad = useLocalBundle ? localBundleInfo : cachedBundleInfo; var loadPath = Utility.CombinePath(LocalURL, bundleInfoToLoad.BundleName); var bundleReq = UnityWebRequestAssetBundle.GetAssetBundle(loadPath, bundleInfoToLoad.Hash); var bundleOp = bundleReq.SendWebRequest(); while (!bundleOp.isDone) { result.SetProgress(bundleOp.progress); yield return(null); } if (!bundleReq.isHttpError && !bundleReq.isNetworkError) { var loadedBundle = new LoadedBundle(bundleInfoToLoad, loadPath, DownloadHandlerAssetBundle.GetContent(bundleReq), useLocalBundle); s_AssetBundles.Add(localBundleInfo.BundleName, loadedBundle); CollectSceneNames(loadedBundle); if (LogMessages) { Debug.Log($"Local bundle Loaded - Name : {localBundleInfo.BundleName}, Hash : {bundleInfoToLoad.Hash }"); } } else { result.Done(BundleErrorCode.NetworkError); yield break; } bundleReq.Dispose(); s_LocalBundles.Add(localBundleInfo.BundleName, localBundleInfo.Hash); } RemoteURL = Utility.CombinePath(localManifest.RemoteURL, localManifest.BuildTarget); #if UNITY_EDITOR if (s_EditorBuildSettings.EmulateWithoutRemoteURL) { RemoteURL = "file://" + Utility.CombinePath(s_EditorBuildSettings.RemoteOutputPath, UnityEditor.EditorUserBuildSettings.activeBuildTarget.ToString()); } #endif Initialized = true; if (LogMessages) { Debug.Log($"Initialize Success \nRemote URL : {RemoteURL} \nLocal URL : {LocalURL}"); } result.Done(BundleErrorCode.Success); }
public IEnumerator DownloadAndCache(string bundleName, System.Action <AssetBundle> handler, int version) { LoadedBundle loadedBundle; if (_bundles.TryGetValue(bundleName, out loadedBundle)) { if (loadedBundle != null) { if (loadedBundle.version == version) { loadedBundle.lastRequest = Time.time; loadedBundle.numRequests++; handler(loadedBundle.bundle); yield break; } } } // Wait for the Caching system to be ready while (!Caching.ready) { yield return(null); } if (!maintainBundleCache) { #if UNITY_2017_1_OR_NEWER Caching.ClearCache(); #else Caching.CleanCache(); #endif } // Load the AssetBundle file from Cache if it exists with the same version or download and store it in the cache string bundleUrl = GetBundleUrl(bundleName); CoreLogger.LogInfo("BundleManager", string.Format("for bundle {0}, full url is {1}", bundleName, bundleUrl)); using (WWW www = WWW.LoadFromCacheOrDownload(bundleUrl, version)) { yield return(www); if (www.error != null) { CoreLogger.LogWarning(name, string.Format("unable to retrieve bundle {0}:{1}", bundleUrl, www.error)); handler(null); yield break; } CoreLogger.LogDebug("BundleManager", string.Format("successfully retrieved bundle {0} from {1}", bundleName, bundleUrl)); if (loadedBundle != null) { CoreLogger.LogDebug("BundleManager", string.Format("New version ({0}) of bundle {1} retrieved - unloading old version ({2}) and caching new one", version, bundleName, loadedBundle.version)); loadedBundle.bundle.Unload(false); loadedBundle.bundle = www.assetBundle; } else { CollectGarbage(); CoreLogger.LogDebug("BundleManager", string.Format("caching version {0} of bundle {1}", version, bundleName)); _bundles[bundleName] = new LoadedBundle() { bundle = www.assetBundle, version = version }; } handler(www.assetBundle); } }
public async Task LoadBundleFromUrl(string bundleName, ObjectDatabaseContentIndexMap objectDatabaseContentIndexMap, string bundleUrl, bool ignoreDependencies = false) { List <string> files; var bundle = ReadBundleHeader(bundleUrl, out files); if (bundle == null) { throw new FileNotFoundException("Could not find bundle", bundleUrl); } // Read and resolve dependencies if (!ignoreDependencies) { foreach (var dependency in bundle.Dependencies) { await LoadBundle(dependency, objectDatabaseContentIndexMap); } } LoadedBundle loadedBundle = null; lock (loadedBundles) { foreach (var currentBundle in loadedBundles) { if (currentBundle.BundleName == bundleName) { loadedBundle = currentBundle; break; } } if (loadedBundle == null) { loadedBundle = new LoadedBundle { BundleName = bundleName, BundleUrl = bundleUrl, Description = bundle, ReferenceCount = 1, Files = files, Streams = new List <Stream>(files.Select(x => (Stream)null)), }; loadedBundles.Add(loadedBundle); } else { loadedBundle.ReferenceCount++; } } // Read objects lock (objects) { foreach (var objectEntry in bundle.Objects) { objects[objectEntry.Key] = new ObjectLocation { Info = objectEntry.Value, LoadedBundle = loadedBundle }; } } // Merge with local (asset bundles) index map contentIndexMap.Merge(bundle.Assets); // Merge with global object database map objectDatabaseContentIndexMap.Merge(bundle.Assets); }