void IfUseErrorType(AssetLoading operation) { bool needLog = false; if (operation.LoadingPattern == AssetLoadingPattern.Simulation) { #if UNITY_EDITOR string[] assetPaths = UnityEditor.AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName(operation.BundleName, operation.Name); if (assetPaths != null && assetPaths.Length > 0) { needLog = true; } #endif } else { if (_loadedAssetBundles.ContainsKey(operation.BundleName)) { var loadedBundle = _loadedAssetBundles[operation.BundleName]; if (loadedBundle.Bundle != null) { if (loadedBundle.Bundle.Contains(operation.Name)) { needLog = true; } } } } if (needLog) { _logger.WarnFormat("AssetBundles {0} Has {1} But You Use The Error Type {2} To Loader", operation.BundleName, operation.Name, operation.ObjectType); } }
private async Task <Dictionary <AssetItem, object> > BuildAndReloadAssets(IEnumerable <AssetItem> assetsToRebuild) { var assetList = assetsToRebuild.ToList(); if (assetList.Count == 0) { return(null); } logger?.Debug($"Starting BuildAndReloadAssets for assets {string.Join(", ", assetList.Select(x => x.Location))}"); var value = Interlocked.Increment(ref loadingAssetCount); AssetLoading?.Invoke(this, new ContentLoadEventArgs(value)); try { // Rebuild the assets await Task.WhenAll(assetList.Select(x => database.Build(x))); logger?.Debug("Assets have been built"); // Unload the previous versions of assets and (re)load the newly build ones. var reloadedObjects = await UnloadAndReloadAssets(assetList); Game.TriggerActiveRenderStageReevaluation(); return(reloadedObjects); } finally { value = Interlocked.Decrement(ref loadingAssetCount); AssetLoaded?.Invoke(this, new ContentLoadEventArgs(value)); logger?.Debug($"Completed BuildAndReloadAssets for assets {string.Join(", ", assetList.Select(x => x.Location))}"); } }
public static void AddLastExt(this LinkedList <AssetLoading> list, AssetLoading assetLoading) { if (assetLoading == null) { throw new Exception("Null AssetLoading!!"); } list.AddLast(assetLoading); }
// 异步LoadAllAssets方法 public void LoadAllAssetsAsync(Action <UnityEngine.Object[]> callback) { if (loadingAll != null) { loadingAll.callback.Add(callback); return; } loadingAll = new AssetLoading <UnityEngine.Object[]>(); loadingAll.callback.Add(callback); GameMain.Instance.StartCoroutine(LoadAllAssetsCoroutine()); }
// 异步GatAB,允许回调为空 public static void GetABAsync(string assetbundleName, Action <AssetBundleRef> callback = null) { AssetBundleRef abRef; if (abDict.TryGetValue(assetbundleName, out abRef)) { // 缓存命中 abRef.Retain(); if (callback != null) { callback(abRef); } } else { AssetLoading <AssetBundleRef> loading; // 检查是否已在loading if (loadingDict.TryGetValue(assetbundleName, out loading)) { //将本次回调添加到load回调就完事了 if (callback != null) { loading.callback.Add(callback); } loading.refCount++; return; } loading = new AssetLoading <AssetBundleRef>(); loadingDict.Add(assetbundleName, loading); if (callback != null) { loading.callback.Add(callback); } // 异步加载 AssetBundleLoader.LoadAsync(assetbundleName, (assetbundle) => { abRef = new AssetBundleRef(assetbundleName, assetbundle); CheckShouldCacheSpriteAsync(abRef, () => { CacheAB(abRef); loadingDict.Remove(assetbundleName); abRef.Retain(loading.refCount - 1); // ref默认是1,所以只需retain refCount - 1 loading.FireCallBack(abRef); }); }); } }
// 释放,命名与destroy区分开 void dealloc() { foreach (KeyValuePair <string, AssetLoading <UnityEngine.Object> > kv in loadingDict) { kv.Value.FireCallBack(null); } loadingDict = null; // 让协程知道该assetbundle已被release if (loadingAll != null) { loadingAll.FireCallBack(null); loadingAll = null; } Unload(true); AssetBundleManager.UnloadAB(this._name); }
// Load All 协程实现 IEnumerator LoadAllAssetsCoroutine() { AssetBundleRequest request = this.assetBundle.LoadAllAssetsAsync(); while (!request.isDone) { if (loadingAll == null) { break; } yield return(false); } if (loadingAll != null) { loadingAll.FireCallBack(request.allAssets); loadingAll = null; } }
// 异步加载资源 public void LoadAsync(string assetName, Action <UnityEngine.Object> callback, Type resType = null) { AssetLoading <UnityEngine.Object> assetLoading; UnityEngine.Object obj; // 先判断该资源是否已经在loading字典中 if (loadingDict.TryGetValue(assetName, out assetLoading)) { // 已在loading,将回调添加上去 assetLoading.callback.Add(callback); return; } // 创建一个loading assetLoading = new AssetLoading <UnityEngine.Object>(); assetLoading.callback.Add(callback); loadingDict.Add(assetName, assetLoading); // 开始异步加载资源 GameMain.Instance.StartCoroutine(LoadAssetCoroutine(assetBundle, assetName, resType == null ? typeof(UnityEngine.Object) : resType)); }
public static void InvokeAssetLoading() => AssetLoading?.Invoke();
//TODO 这个方法有些复杂,说明需要简化逻辑 public override void LoadAsync(GameResType type, string name, Action <UnityEngine.Object> callback, Type resType = null) { GameBundleInfo data; // 检查资源 if (CheckRes(type, name, out data)) { AssetBundleRef abRef; /* * 测试发现,异步从ab包加载资源时,即使该assetbundle已被unload(true),仍可以载到奇怪的资源,且能被添加到场景上 * 而loader被释放可能引起assetbundle被unload */ Action <UnityEngine.Object> checkCallBack = (asset) => //检查异步加载资源结束时,是否该loader已被释放 { if (abrDict == null || loadingDict == null) // 为null视为已释放 { callback(null); // 直接回调null } else { callback(asset); // 正常回调上层 } }; if (abrDict.TryGetValue(data.assetbundle, out abRef)) { abRef.LoadAsync(name, checkCallBack); // 缓存命中 } else { // 缓存未命中,则要去加载ab,先声明ab载完回调 Action <AssetBundleRef> loadABCallback = (assetbundleRef) => { if (assetbundleRef == null) { checkCallBack(null); } else { assetbundleRef.LoadAsync(name, checkCallBack); } }; /* * loadAssetbundle 可以考虑在继承monoLoader的情况下,自己startCoroutine,就不必处理协程结束,而自己已经被销毁的情况 */ AssetLoading <AssetBundleRef> loading; // 如果已经在异步load assetbundle if (loadingDict.TryGetValue(data.assetbundle, out loading)) { //将本次回调添加到load回调就完事了 loading.callback.Add(loadABCallback); return; } // 创建一个loading loading = new AssetLoading <AssetBundleRef>(); loadingDict.Add(data.assetbundle, loading); loading.callback.Add(loadABCallback); // 异步load Assetbundle LoadABAsync(data.assetbundle, (assetbundleRef) => // 本地缓存未命中,向AssetManager异步请求AssetBundle { // 如果loader自身已被释放 if (abrDict == null || loadingDict == null) { loading.FireCallBack(null); // 回调null } // 正常添加到缓存,并回调 loadingDict.Remove(data.assetbundle); loading.FireCallBack(assetbundleRef); }); } } else { // 没找到这资源 callback(null); } }
private void View_ScriptNotify(object sender, NotifyEventArgs e) { var key = e.Value.Substring(0, 4); var value = e.Value.Substring(4); switch (key) { // Loading assets case "LOAD": { AssetLoading?.Invoke(this, EventArgs.Empty); break; } // Assets loaded case "LODD": { _view.Opacity = 1; AssetLoaded?.Invoke(this, EventArgs.Empty); break; } // Camera alpha angle in radians case "ALPH": { AlphaInDegrees = GetDegreeFromRadian(double.Parse(value)); break; } // Camera beta angle in radians case "BETA": { BetaInDegrees = GetDegreeFromRadian(double.Parse(value)); break; } // Camera radius case "RADI": { RadiusPercentage = double.Parse(value); break; } // Animations are supported case "ANIM": { if (_commandGrid == null) { return; } _commandGrid.Visibility = Visibility.Visible; var animationNames = value.Split(','); if (_animationList != null) { _animationList.Items.Clear(); foreach (var animName in animationNames) { _animationList.Items.Add(animName); } _animationList.SelectedIndex = 0; _playSymbol.Visibility = Visibility.Collapsed; _pauseSymbol.Visibility = Visibility.Visible; } break; } // No animation case "NANM": { if (_commandGrid != null) { _commandGrid.Visibility = Visibility.Collapsed; } break; } // Current animation frame case "FRAM": { if (_animationSlider == null || !_sliderLayoutUpdated) { return; } var position = Math.Min(1, Math.Max(0, double.Parse(value))); // Making sure we are not overwhelming the system _sliderLayoutUpdated = false; _lastValueSetFromAnimation = position * 99.0; _animationSlider.Value = _lastValueSetFromAnimation; break; } } }