public AssetBundleInfo AssetBundleInfoFromBundleName(string bundleName) { foreach (var list in storage.Values) { var candidate = list.assetBundles.Where(bundle => bundle.bundleName == bundleName).FirstOrDefault(); if (!AssetBundleInfo.IsEmpty(candidate)) { return(candidate); } } return(new AssetBundleInfo()); }
public bool IsAssetBundleCachedOnStorage(string bundleName) { var candidateAssetBundle = bundleListStorage.AssetBundleInfoFromBundleName(bundleName); if (AssetBundleInfo.IsEmpty(candidateAssetBundle)) { return(false); } var url = GetAssetBundleDownloadUrl(bundleName); var hash = Hash128.Parse(candidateAssetBundle.hash); return(Caching.IsVersionCached(url, hash)); }
/** * load specific type Asset from AssetBundle. * dependency of AssetBundle will be solved automatically. * * note: * this timeoutSec param is enabled only for downloading AssetBundle from web. * * 複数のAssetBundleに依存していて、それのうちのひとつとかがtimeoutしたら */ public IEnumerator LoadAsset <T>( string assetName, Action <string, T> loadSucceeded, Action <string, AssetBundleLoadError, string, AutoyaStatus> loadFailed, double timeoutSec = 0) where T : UnityEngine.Object { if (!assetNamesAndAssetBundleNamesDict.ContainsKey(assetName)) { loadFailed(assetName, AssetBundleLoadError.NotContained, string.Empty, new AutoyaStatus()); yield break; } var timeoutTick = (DateTime.UtcNow + TimeSpan.FromSeconds(timeoutSec)).Ticks; if (timeoutSec == 0) { timeoutTick = 0; } var bundleName = assetNamesAndAssetBundleNamesDict[assetName]; var assetBundleInfo = bundleListStorage.AssetBundleInfoFromBundleName(bundleName); if (AssetBundleInfo.IsEmpty(assetBundleInfo)) { // no assetBundleInfo found. loadFailed(assetName, AssetBundleLoadError.NoAssetBundleFoundInList, "no assetBundle found:" + bundleName + " in list.", new AutoyaStatus()); yield break; } var crc = assetBundleInfo.crc; var hash = Hash128.Parse(assetBundleInfo.hash); var coroutine = LoadAssetBundleOnMemory( bundleName, assetName, crc, hash, loadSucceeded, loadFailed, timeoutTick, false, new List <string>() ); while (coroutine.MoveNext()) { yield return(null); } }
/** * load assetBundle on memory. */ private IEnumerator LoadAssetBundleOnMemory <T>( string bundleName, string assetName, uint crc, Hash128 hash, Action <string, T> loadSucceeded, Action <string, AssetBundleLoadError, string, AutoyaStatus> loadFailed, long timeoutTick, bool isDependency = false, List <string> loadingDependentBundleNames = null ) where T : UnityEngine.Object { while (!Caching.ready) { yield return(null); } var assetBundleInfo = bundleListStorage.AssetBundleInfoFromBundleName(bundleName); if (AssetBundleInfo.IsEmpty(assetBundleInfo)) { // no assetBundleInfo found. loadFailed(assetName, AssetBundleLoadError.NoAssetBundleFoundInList, "no assetBundle found:" + bundleName + " in list.", new AutoyaStatus()); yield break; } var dependentBundleNames = assetBundleInfo.dependsBundleNames; var dependentBundleLoadErrors = new List <DependentBundleError>(); /* * resolve dependencies. */ { if (dependentBundleNames.Any()) { var coroutines = new Dictionary <string, IEnumerator>(); foreach (var dependentBundleName in dependentBundleNames) { if (loadingDependentBundleNames != null) { if (loadingDependentBundleNames.Contains(dependentBundleName)) { continue; } } // skip if assetBundle is already loaded on memory. if (onMemoryCache.ContainsKey(dependentBundleName) && onMemoryCache[dependentBundleName] != null) { continue; } var dependedBundleInfo = bundleListStorage.AssetBundleInfoFromBundleName(dependentBundleName); if (AssetBundleInfo.IsEmpty(dependedBundleInfo)) { // skip empty info. continue; } var dependentBundleCrc = dependedBundleInfo.crc; var dependentBundleHash = Hash128.Parse(dependedBundleInfo.hash); // set UnityEngine.Object for request. this asset will never use directory. var loadCoroutine = LoadAssetBundleOnMemory <UnityEngine.Object>( dependentBundleName, string.Empty,// bundleName not required. dependentBundleCrc, dependentBundleHash, (depBundleName, depObj) => { // do nothing. this bundle is currently on memory. }, (depBundleName, depErr, depReason, autoyaStatus) => { // collect error for this dependent bundle loading. dependentBundleLoadErrors.Add(new DependentBundleError(depBundleName, depErr, depReason, autoyaStatus)); }, timeoutTick, true, // this loading is for resolve dependency of root asset. no need to return any instances. loadingDependentBundleNames ); if (loadingDependentBundleNames != null) { loadingDependentBundleNames.Add(dependentBundleName); } coroutines[dependentBundleName] = loadCoroutine; } if (coroutines.Count != 0) { while (true) { if (!coroutines.Where(c => c.Value != null).Any()) { // load done. break; } for (var i = 0; i < coroutines.Count; i++) { var loadingAssetBundleName = coroutines.Keys.ToArray()[i]; var coroutine = coroutines[loadingAssetBundleName]; if (coroutine == null) { continue; } if (!coroutine.MoveNext()) { coroutines[loadingAssetBundleName] = null; } } yield return(null); } // all dependencies are loaded on memory. } } } var url = GetAssetBundleDownloadUrl(bundleName); // check now loading or not. if same bundle is already under loading, wait it here. if (loadingAssetBundleNames.Contains(bundleName)) { while (loadingAssetBundleNames.Contains(bundleName)) { yield return(null); } // check downloaded bundle is correctly cached or not. var isCached = Caching.IsVersionCached(url, hash); if (!isCached) { loadFailed(assetName, AssetBundleLoadError.DownloadFailed, "caching failed.", new AutoyaStatus()); yield break; } } // assetBundle is already allocated on memory. if (onMemoryCache.ContainsKey(bundleName)) { var isCached = Caching.IsVersionCached(url, hash); if (isCached) { // if current target is dependency, dependent assetBundle is already on memory. and no need to load it. if (isDependency) { yield break; } // start loading assetBundle on memory. var loadOnMemoryCachedAssetCoroutine = LoadOnMemoryAssetAsync(bundleName, assetName, loadSucceeded, loadFailed); while (loadOnMemoryCachedAssetCoroutine.MoveNext()) { yield return(null); } // loading asset from on memory cache is done. yield break; } // assetBundle is cached on memory but it's not target hashed bundle. need to download other one. var oldOnMemoryAssetBundle = onMemoryCache[bundleName]; // remove from on memory cache. UnloadOnMemoryAssetBundle(bundleName); } /* * assetBundle is.. * not yet cached (or) already cached. * not allocated on memory. * * assetBundle is not on memory yet. start downloading. */ // binded block. using (var loadingConstraint = new AssetBundleLoadingConstraint(bundleName, loadingAssetBundleNames)) { /* * download bundle or load donwloaded bundle from cache. * load to memory. */ { var downloadCoroutine = DownloadAssetThenCacheAndLoadToMemory(bundleName, assetName, url, crc, hash, loadFailed, timeoutTick); while (downloadCoroutine.MoveNext()) { yield return(null); } if (!onMemoryCache.ContainsKey(bundleName)) { // error is already fired in above. yield break; } if (!isDependency) { /* * break if dependent bundle has load error. */ if (dependentBundleLoadErrors.Any()) { var loadErrorBundleMessages = new StringBuilder(); loadErrorBundleMessages.Append("failed to load/download dependent bundle:"); foreach (var dependentBundleLoadError in dependentBundleLoadErrors) { loadErrorBundleMessages.Append("bundleName:"); loadErrorBundleMessages.Append(dependentBundleLoadError.bundleName); loadErrorBundleMessages.Append(" error:"); loadErrorBundleMessages.Append(dependentBundleLoadError.err); loadErrorBundleMessages.Append(" reason:"); loadErrorBundleMessages.Append(dependentBundleLoadError.reason); loadErrorBundleMessages.Append(" autoyaStatus:"); loadErrorBundleMessages.Append(" inMaintenance:" + dependentBundleLoadError.status.inMaintenance); loadErrorBundleMessages.Append(" isAuthFailed:" + dependentBundleLoadError.status.isAuthFailed); } loadFailed(assetName, AssetBundleLoadError.FailedToLoadDependentBundles, loadErrorBundleMessages.ToString(), new AutoyaStatus()); yield break; } /* * load asset from on memory AssetBundle. */ var loadAssetCoroutine = LoadOnMemoryAssetAsync(bundleName, assetName, loadSucceeded, loadFailed); while (loadAssetCoroutine.MoveNext()) { yield return(null); } } } } }