Esempio n. 1
0
        public static BundleAsyncOperation <AssetbundleBuildManifest> GetManifest()
        {
            var result = new BundleAsyncOperation <AssetbundleBuildManifest>();

            s_Helper.StartCoroutine(CoGetManifest(result));
            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// acutally download assetbundles load from cache if cached
        /// </summary>
        /// <param name="manifest">manifest you get from GetManifest() function</param>
        /// <param name="subsetNames">names that you interested among full bundle list(optional)</param>
        public static BundleAsyncOperation <bool> DownloadAssetBundles(AssetbundleBuildManifest manifest, IEnumerable <string> subsetNames = null)
        {
            var result = new BundleAsyncOperation <bool>();

            s_Helper.StartCoroutine(CoDownloadAssetBundles(manifest, subsetNames, result));
            return(result);
        }
Esempio n. 3
0
        public static BundleAsyncOperation Initialize(bool autoReloadBundle = true)
        {
            var result = new BundleAsyncOperation();

            s_Helper.StartCoroutine(CoInitalizeLocalBundles(result, autoReloadBundle));
            return(result);
        }
        /// <summary>
        /// acutally download assetbundles load from cache if cached
        /// </summary>
        /// <param name="hardUnload">hard unload reloaded bundle</param>
        /// <returns>returns bundle has been reloaded</returns>
        public static BundleAsyncOperation <bool> DownloadAssetBundles(AssetbundleBuildManifest manifest, bool hardUnload = false)
        {
            var result = new BundleAsyncOperation <bool>();

            s_Helper.StartCoroutine(CoDownloadAssetBundles(manifest, hardUnload, result));
            return(result);
        }
        static IEnumerator CoGetManifest(BundleAsyncOperation <AssetbundleBuildManifest> result)
        {
            if (!Initialized)
            {
                Debug.LogError("Do Initialize first");
                result.Done(BundleErrorCode.NotInitialized);
                yield break;
            }

#if UNITY_EDITOR
            if (UseAssetDatabase)
            {
                result.Result = new AssetbundleBuildManifest();
                result.Done(BundleErrorCode.Success);
                yield break;
            }
#endif

            var manifestReq = UnityWebRequest.Get(Utility.CombinePath(RemoteURL, AssetbundleBuildSettings.ManifestFileName).Replace('\\', '/'));
            yield return(manifestReq.SendWebRequest());

            if (result.IsCancelled)
            {
                manifestReq.Dispose();
                yield break;
            }

            if (manifestReq.isHttpError || manifestReq.isNetworkError)
            {
                result.Done(BundleErrorCode.NetworkError);
                yield break;
            }

            var remoteManifestJson = manifestReq.downloadHandler.text;
            manifestReq.Dispose();

            if (!AssetbundleBuildManifest.TryParse(remoteManifestJson, out var remoteManifest))
            {
                result.Done(BundleErrorCode.ManifestParseError);
                yield break;
            }

            result.Result = remoteManifest;
            result.Done(BundleErrorCode.Success);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
        }
        static IEnumerator CoDownloadAssetBundles(AssetbundleBuildManifest remoteManifest, bool hardUnload, BundleAsyncOperation <bool> result)
        {
            if (!Initialized)
            {
                Debug.LogError("Do Initialize first");
                result.Done(BundleErrorCode.NotInitialized);
                yield break;
            }

            if (UseAssetDatabase)
            {
                result.Done(BundleErrorCode.Success);
                yield break;
            }

            var startTime = Time.realtimeSinceStartup;

            result.SetIndexLength(remoteManifest.BundleInfos.Count);
            bool bundleReplaced = false; //bundle has been replaced

            for (int i = 0; i < remoteManifest.BundleInfos.Count; i++)
            {
                result.SetCurrentIndex(i);
                var bundleInfo  = remoteManifest.BundleInfos[i];
                var localBundle = s_LocalBundles.TryGetValue(bundleInfo.BundleName, out var localHash) && localHash == bundleInfo.Hash;
                var isCached    = Caching.IsVersionCached(bundleInfo.AsCached);
                result.SetCachedBundle(isCached);

                var loadURL = localBundle ? Path.Combine(LocalURL, bundleInfo.BundleName) : Path.Combine(RemoteURL, bundleInfo.BundleName);
                if (LogMessages)
                {
                    Debug.Log($"Loading Bundle Name : {bundleInfo.BundleName}, loadURL {loadURL}, isLocalBundle : {localBundle}, 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 = localBundle ? 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(hardUnload);
                        if (previousBundle.RequestForReload != null)
                        {
                            previousBundle.RequestForReload.Dispose(); //dispose reload bundle
                        }
                        s_AssetBundles.Remove(bundleInfo.BundleName);
                    }

                    var loadedBundle = new LoadedBundle(bundleInfo, loadURL, DownloadHandlerAssetBundle.GetContent(bundleReq), localBundle);
                    s_AssetBundles.Add(bundleInfo.BundleName, loadedBundle);
                    CollectSceneNames(loadedBundle);
                    if (LogMessages)
                    {
                        Debug.Log($"Loading Bundle Name : {bundleInfo.BundleName} Complete");
                    }
                    bundleReq.Dispose();
                }

                Caching.MarkAsUsed(bundleInfo.AsCached);
            }

            var timeTook = Time.realtimeSinceStartup - startTime;

            if (LogMessages)
            {
                Debug.Log($"CacheUsed Before Cleanup : {Caching.defaultCache.spaceOccupied} bytes");
            }
            Caching.ClearCache((int)timeTook + 600);
            if (LogMessages)
            {
                Debug.Log($"CacheUsed After CleanUp : {Caching.defaultCache.spaceOccupied} bytes");
            }

            PlayerPrefs.SetString("CachedManifest", JsonUtility.ToJson(remoteManifest));
            GlobalBundleHash = remoteManifest.GlobalHash.ToString();
            result.Result    = bundleReplaced;
            result.Done(BundleErrorCode.Success);
        }