bool UnloadAssetBundle(string path, bool force = false)
        {
            var cachePath         = path.ToLower();
            var loadedAssetBundle = this.TryGetLoadedAssetBundle(cachePath);

            if (loadedAssetBundle == null)
            {
                return(false);
            }

            var isManifest = path == ResConfig.MAINIFEST;
            var bundleName = isManifest ? path : ResConfig.ConvertToBundleName(path) + ResConfig.BUNDLE_EXTENSION;

            // Try unload bundle assets, and remove from cache
            if (force)
            {
                loadedAssetBundle.ReferencedCount = 0;
            }
            else
            {
                loadedAssetBundle.ReferencedCount--;
            }

            // Check referencedCount
            var unload = false;

            if (loadedAssetBundle.ReferencedCount <= 0)
            {
                unload = true;
                loadedAssetBundle.Unload();
                _assetBundles.Remove(cachePath);
                this.DebugDeallocBundle(cachePath);
                if (isManifest)
                {
                    _manifest = null;
                }
            }

            // Try unload depenceBundle
            if (unload == true && _dependenceInfos.ContainsKey(bundleName))
            {
                var dependencies = _dependenceInfos[bundleName];
                for (var i = 0; i < dependencies.Length; ++i)
                {
                    var dependencePath = ResConfig.ReverseFromBundleName(dependencies[i]);
                    this.UnloadAssetBundle(dependencePath, force);
                }
                _dependenceInfos.Remove(bundleName);
            }

            return(true);
        }
        LoadedAssetBundle LoadAssetBundle(string path, bool isDependence = false)
        {
            this.EnsureManifest();
            var cachePath         = path.ToLower();
            var loadedAssetBundle = this.TryGetLoadedAssetBundle(cachePath);

            if (loadedAssetBundle != null)
            {
                loadedAssetBundle.ReferencedCount++;
                return(loadedAssetBundle);
            }

            var isManifest = path == ResConfig.MAINIFEST;
            var bundleName = isManifest ? path : ResConfig.ConvertToBundleName(path) + ResConfig.BUNDLE_EXTENSION;

            // Load dependencies
            if (isDependence == false)
            {
                var dependencies = this.GetDependencies(bundleName, path);
                for (var i = 0; i < dependencies.Length; ++i)
                {
                    var dependencePath   = ResConfig.ReverseFromBundleName(dependencies[i]);
                    var dependenceBundle = this.LoadAssetBundle(dependencePath, true);
                    if (dependenceBundle == null)
                    {
                        LogManager.Error(string.Format(
                                             "ResManager::LoadAssetFromBundle error, dependence({0}) is null!",
                                             dependencePath
                                             ));
                    }
                }
            }

            // Load & cache assetBundle
            loadedAssetBundle = new LoadedAssetBundle(path, bundleName);
            loadedAssetBundle.ReferencedCount = 1;
            _assetBundles.Add(cachePath, loadedAssetBundle);
            this.DebugAllocBundle(cachePath);

            return(loadedAssetBundle);
        }
示例#3
0
        public static void ResetBundleName(ref AssetBundleBuild buildInfo)
        {
            var assetBundleNameWithoutExtension = buildInfo.assetBundleName.ReplaceLast(ResConfig.BUNDLE_EXTENSION, "");

            assetBundleNameWithoutExtension = ResConfig.ConvertToBundleName(assetBundleNameWithoutExtension);
            var assetBundleName = assetBundleNameWithoutExtension + ResConfig.BUNDLE_EXTENSION;

            buildInfo.assetBundleName = assetBundleName;

            foreach (var assetName in buildInfo.assetNames)
            {
                var assetImporter = AssetImporter.GetAtPath(assetName);
                if (assetImporter == null)
                {
                    LogManager.Error("ResetBundleName error, asset not found: " + assetName);
                    continue;
                }
                if (assetImporter.assetBundleName != assetBundleName)
                {
                    assetImporter.assetBundleName = assetBundleName;
                }
            }
        }
示例#4
0
        IEnumerator HotUpdating()
        {
            // Get local version file at first
            var localVersionFile = GetLocalVersionFile();

            // Get remote version file and compare
            // Download remote version file and save to temporary directory
            var file   = ResConfig.ConvertToBundleName(ResConfig.VERSION_FILE) + ResConfig.BUNDLE_EXTENSION;
            var assets = new List <string>();

            assets.Add(file);
            var fileFolder    = "resversionfile_tempfolder";
            var fileDirectory = ResConfig.MOBILE_HOTUPDATE_PATH + "/" + fileFolder;
            var failure       = false;

            byte[] downloadBytes = null;
            yield return(this.StartCoroutine(this.DownloadAssetsAsyncAndSave(
                                                 ResConfig.SERVER_URL + "/",
                                                 assets,
                                                 (processInfo, www) => {
                if (string.IsNullOrEmpty(processInfo.Error) == false)
                {
                    failure = true;
                    processInfo.Index = -1;
                    processInfo.Count = 0;
                    this.NotifyHotUpdate(processInfo);
                }
                else
                {
                    var length = www.bytesDownloaded;
                    // var length = www.bytes.Length;
                    downloadBytes = new byte[length];
                    Array.Copy(www.bytes, 0, downloadBytes, 0, length);
                }
            },
                                                 fileDirectory
                                                 )));

            if (failure)
            {
                yield break;
            }
            var txtAsset = this.Load <TextAsset>(fileFolder + "/" + ResConfig.VERSION_FILE);

            if (txtAsset == null)
            {
                var processInfo = new ProcessInfo();
                processInfo.File  = ResConfig.VERSION_FILE;
                processInfo.Index = -1;
                processInfo.Count = 0;
                processInfo.Error = "Download version file error";
                this.NotifyHotUpdate(processInfo);
                yield break;
            }
            var txt = txtAsset.text;
            var remoteVersionFile = ResVersionFile.UnSerialize(txt);

            // Unload asset bundle
            this.UnloadAsset(fileFolder + "/" + ResConfig.VERSION_FILE);

            // Hotupdating(download and save)
            var diffInfos = ResVersionFile.GetDiffInfos(localVersionFile, remoteVersionFile);

            if (diffInfos.Count <= 0)
            {
                this.NotifyNoHotUpdate();
                yield break;
            }
            assets.Clear();
            for (int i = 0; i < diffInfos.Count; ++i)
            {
                var asset = diffInfos[i].File;
                assets.Add(asset);
            }
            var count           = assets.Count;
            var downloadedCount = 0;

            yield return(this.StartCoroutine(this.DownloadAssetsAsyncAndSave(
                                                 ResConfig.SERVER_URL + "/",
                                                 assets,
                                                 (processInfo, www) => {
                downloadedCount++;
                processInfo.Index = downloadedCount - 1;
                processInfo.Count = assets.Count;
                this.NotifyHotUpdate(processInfo);
            }
                                                 )));

            // Finally replace local version file
            FileUtility.WriteFile(ResConfig.MOBILE_HOTUPDATE_PATH + "/" + file, downloadBytes, downloadBytes.Length, false);
        }
示例#5
0
        static void _AppendDependencies(AssetBundleBuild buildInfo, string name, List <AssetBundleBuild> buildInfos)
        {
            var dependencies = AssetDatabase.GetDependencies(name, true);

            foreach (var dependence in dependencies)
            {
                // Exclude assets not in Assets
                if (dependence.StartsWith("Assets") == false)
                {
                    LogManager.Warning(string.Format(
                                           "asset({0}) depends on asset({1}) not in Assets!",
                                           name,
                                           dependence
                                           ));
                    continue;
                }

                // Exclude scripts
                if (dependence.EndsWith(".cs") || dependence.EndsWith(".js"))
                {
                    continue;
                }

                if (dependence.StartsWith("Assets/" + ResConfig.RES_ROOT))
                {
                    if (name != dependence &&
                        dependence.EndsWith(".shader") == false)
                    {
                        LogManager.Warning(string.Format(
                                               "asset({0}) depends on asset({1}) in Assets/Res, which should be prevented!",
                                               name,
                                               dependence
                                               ));
                    }
                    continue;
                }

                // Set atlas name
                if (dependence.StartsWith("Assets/" + ResConfig.UI_TEXTURE) &&
                    dependence.StartsWith("Assets/" + ResConfig.UI_TEXTURE_RUNTIME) == false)
                {
                    var textureImporter = AssetImporter.GetAtPath(dependence) as TextureImporter;
                    ResTextureAutoConfigurer.ConfigureUITexture(textureImporter);
                }

                var assetName       = dependence;
                var assetBundleName = dependence;
                var dependenceRoot  = dependence.ReplaceFirst("Assets", ResConfig.DEPENDENCIES_ROOT);
                if (ResConfig.IsFolderAsBundleName(dependence))
                {
                    var fileName = Path.GetFileName(dependence);
                    assetBundleName = dependenceRoot.ReplaceLast("/" + fileName, "") + ResConfig.BUNDLE_EXTENSION;
                }
                else
                {
                    assetBundleName = dependenceRoot + ResConfig.BUNDLE_EXTENSION;
                }

                var index = TryGetBuildInfo(buildInfos, assetBundleName);
                if (index == -1)
                {
                    var dependenceBuildInfo = new AssetBundleBuild();
                    dependenceBuildInfo.assetNames      = new string[] { assetName };
                    dependenceBuildInfo.assetBundleName = assetBundleName;
                    buildInfos.Add(dependenceBuildInfo);
                    _AppendDependencies(dependenceBuildInfo, assetName, buildInfos);
                }
                else
                {
                    var dependenceBuildInfo = buildInfos[index];
                    var assetNames          = dependenceBuildInfo.assetNames.ToList();
                    if (assetNames.Contains(assetName))
                    {
                        continue;
                    }

                    assetNames.Add(assetName);
                    dependenceBuildInfo.assetNames = assetNames.ToArray();
                    buildInfos[index] = dependenceBuildInfo;
                    _AppendDependencies(dependenceBuildInfo, assetName, buildInfos);
                }
            }
        }
示例#6
0
        IEnumerator DownloadAssetsAsyncAndSave(string urlPrefix, List <string> assets, Action <ProcessInfo, WWW> callback, string outputDirectory = null, int returnStep = 1)
        {
            _assetsCount           = assets.Count;
            _downloadedAssetsCount = 0;
            for (int i = 0; i < assets.Count; ++i)
            {
                var path      = assets[i];
                var file      = Path.GetFileName(path);
                var url       = urlPrefix + path;
                var coroutine = this.StartCoroutine(this.DownloadAssetAsync(url, (www) => {
                    _downloadedAssetsCount++;

                    // Define error message
                    var error = "";
                    if (www == null)
                    {
                        error = "Timeout";
                    }
                    else if (string.IsNullOrEmpty(www.error) == false)
                    {
                        error = www.error;
                    }

                    // Create processInfo
                    var processInfo   = new ProcessInfo();
                    processInfo.File  = file;
                    processInfo.Index = i;
                    processInfo.Count = assets.Count;
                    if (string.IsNullOrEmpty(error) == false)
                    {
                        processInfo.Error = string.Format("Download failure! asset({0}) error({1})", path, error);
                        callback(processInfo, www);
                        return;
                    }

                    // Compress or just save asset
                    var exception = "";
                    var fullpath  = (string.IsNullOrEmpty(outputDirectory) ? ResConfig.MOBILE_HOTUPDATE_PATH : outputDirectory) + "/" + path;
                    try
                    {
                        var decompressable    = ResConfig.IsCompressable(fullpath);
                        var decompressFailure = false;
                        if (decompressable)
                        {
                            try
                            {
                                var length = www.bytesDownloaded;
                                // var length = www.bytes.Length;
                                FileUtility.DeCompressBuffer(www.bytes, length, fullpath);
                            }
                            catch (Exception e)
                            {
                                exception         = e.Message;
                                decompressFailure = true;
                            }
                        }

                        // Dont decompress or decompress failure, then
                        // just copy
                        if (decompressable == false ||
                            (decompressable == true && decompressFailure == true))
                        {
                            var length = www.bytesDownloaded;
                            // var length = www.bytes.Length;
                            FileUtility.WriteFile(fullpath, www.bytes, length, false);
                        }
                    }
                    catch (Exception e)
                    {
                        exception = e.Message;
                    }
                    finally
                    {
                        if (File.Exists(fullpath))
                        {
                            LogManager.Log(string.Format(
                                               "Save successfully! asset({0}) fullpath({1})",
                                               path,
                                               fullpath
                                               ));
                            processInfo.Error = string.Empty;
                        }
                        else
                        {
                            LogManager.Error(string.Format(
                                                 "Save failure! asset({0}) fullpath({1}) exception({2})",
                                                 path,
                                                 fullpath,
                                                 exception
                                                 ));
                            processInfo.Error = string.Format("Save failure! asset({0}) exception({1})", path, exception);
                        }
                    }

                    callback(processInfo, www);
                }));

                if (i % returnStep == 0)
                {
                    yield return(coroutine);
                }
            }

            // Check finished or not
            while (_downloadedAssetsCount < _assetsCount)
            {
                yield return(1);
            }
            yield break;
        }