Пример #1
0
 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());
 }
Пример #2
0
        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));
        }
Пример #3
0
        /**
         *              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);
            }
        }
Пример #4
0
        /**
         *              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);
                        }
                    }
                }
            }
        }