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); }
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; } } }
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); }
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); } } }
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; }