/// <summary> /// 打包AssetBundle /// </summary> public static void BuildAllAssetBundlesToTarget(BuildTarget target , BuildAssetBundleOptions options) { string manifest_file = EditorCommon.BUILD_PATH + "/" + Common.MAIN_MANIFEST_FILE_NAME; AssetBundleManifest old_manifest = Common.LoadMainManifestByPath(manifest_file); if (!Directory.Exists(EditorCommon.BUILD_PATH)) { Directory.CreateDirectory(EditorCommon.BUILD_PATH); } BuildPipeline.BuildAssetBundles(EditorCommon.BUILD_PATH, options, target); AssetDatabase.Refresh(); AssetBundleManifest new_manifest = Common.LoadMainManifestByPath(manifest_file); ComparisonAssetBundleManifest(old_manifest, new_manifest); ExportResourcesManifestFile(new_manifest); string resoures_manifest_file = EditorCommon.BUILD_PATH + "/" + Common.RESOURCES_MANIFEST_FILE_NAME; ResourcesManifest resoureces_manifest = Common.LoadResourcesManifestByPath(resoures_manifest_file); CompressAssetBundles(resoureces_manifest, ref resoureces_manifest); resoureces_manifest.Save(resoures_manifest_file); CopyNativeAssetBundleToStreamingAssets(resoureces_manifest); EditorUtility.ClearProgressBar(); AssetDatabase.Refresh(); }
/// <summary> /// 写入下载缓存信息,用于断点续传 /// </summary> void SaveDownloadCacheData() { if (CurrentState < emState.UpdateAssetBundle) { return; } if (!Directory.Exists(Common.CACHE_PATH)) { return; } //载入新的Manifest string new_manifest_name = Common.GetCacheFileFullName(Common.MAIN_MANIFEST_FILE_NAME); AssetBundleManifest new_manifest = Common.LoadMainManifestByPath(new_manifest_name); if (new_manifest == null) { return; } //先尝试读取旧的缓存信息,再保存现在已经下载的数据 //PS:由于只有版本完整更新完才会移动Cache目录,且玩家可能多次尝试下载更新,所以必须保留旧的缓存信息 DownloadCache cache = new DownloadCache(); cache.Load(Common.DOWNLOADCACHE_FILE_PATH); if (ab_download_ != null && ab_download_.CompleteDownloads != null && ab_download_.CompleteDownloads.Count > 0) { for (int i = 0; i < ab_download_.CompleteDownloads.Count; ++i) { string assetbundle_name = ab_download_.CompleteDownloads[i]; Hash128 hash_code = new_manifest.GetAssetBundleHash(assetbundle_name); if (hash_code.isValid && !cache.Data.AssetBundles.ContainsKey(assetbundle_name)) { DownloadCacheData.AssetBundle elem = new DownloadCacheData.AssetBundle() { AssetBundleName = assetbundle_name, Hash = hash_code.ToString(), }; Debug.Log(cache.Data.AssetBundles.Count + " - Cache Add:" + assetbundle_name); cache.Data.AssetBundles.Add(assetbundle_name, elem); } } } if (cache.HasData()) { cache.Save(Common.DOWNLOADCACHE_FILE_PATH); } }
/// <summary> /// 加载粒度信息 /// </summary> void LoadAssetBundleGranularityInfo() { Dictionary <string, int> granularity_table = new Dictionary <string, int>(); //载入ResourcesManifest文件 ResourcesManifest resoureces_manifest = new ResourcesManifest(); resoureces_manifest.Load(EditorCommon.RESOURCES_MANIFEST_FILE_PATH); if (resoureces_manifest.Data.AssetBundles.Count == 0) { return; } //载入AssetBunbleManifest string full_name = EditorCommon.MAIN_MANIFEST_FILE_PATH; AssetBundleManifest manifest = Common.LoadMainManifestByPath(full_name); if (manifest == null) { return; } //遍历AssetBundle foreach (var ab_name in manifest.GetAllAssetBundles()) { AssetBundle ab = EditorCommon.LoadAssetBundleFromName(ab_name); if (ab != null) { //获得所有的AssetBundle依赖 List <string> de_abs = new List <string>(manifest.GetAllDependencies(ab_name)); //获得所有依赖的AssetBundle的Asset List <string> de_assets = new List <string>(); foreach (var ab_name1 in de_abs) { AssetBundle ab1 = EditorCommon.LoadAssetBundleFromName(ab_name1); if (ab1 != null) { de_assets.AddRange(ab1.GetAllAssetNames()); ab1.Unload(false); } } //获得所有的Asset List <string> result = new List <string>(); List <string> assets = new List <string>(ab.GetAllAssetNames()); SearchValidAsset(assets, de_assets, ref result); foreach (var name in result) { if (granularity_table.ContainsKey(name)) { granularity_table[name] = granularity_table[name] + 1; } else { granularity_table.Add(name, 1); } } ab.Unload(false); } } //刷新UI数据 AssetNodeGroup group = gui_multi_select_.Group as AssetNodeGroup; group.Root.RefreshGranularity("assets", granularity_table); }
/// <summary> /// 更新AssetBundle /// </summary> IEnumerator StartUpdateAssetBundle() { if (ErrorCode != emErrorCode.None) { yield break; } UpdateCompleteValue(0f, 0f); //载入新的ResourcesManifest ResourcesManifest old_resource_manifest = AssetBundleManager.Instance.ResourcesManifest; string file = Common.GetCacheFileFullName(Common.RESOURCES_MANIFEST_FILE_NAME); ResourcesManifest new_resources_manifest = Common.LoadResourcesManifestByPath(file); if (new_resources_manifest == null) { Error(emErrorCode.LoadNewResourcesManiFestFailed, "Can't load new verion ResourcesManifest!"); yield break; } //载入MainManifest AssetBundleManifest manifest = AssetBundleManager.Instance.MainManifest; file = Common.GetCacheFileFullName(Common.MAIN_MANIFEST_FILE_NAME); AssetBundleManifest new_manifest = Common.LoadMainManifestByPath(file); if (new_manifest == null) { Error(emErrorCode.LoadNewMainManifestFailed, "Can't find new version MainManifest!"); yield break; } //获取需下载的资源列表与删除的资源的列表 List <string> download_files = new List <string>(); List <string> delete_files = new List <string>(); CompareAssetBundleDifference(ref download_files, ref delete_files, manifest, new_manifest, old_resource_manifest, new_resources_manifest); //删除已废弃的文件 if (delete_files.Count > 0) { for (int i = 0; i < delete_files.Count; ++i) { string full_name = Common.GetFileFullName(delete_files[i]); if (File.Exists(full_name)) { File.Delete(full_name); yield return(0); } } } //更新所有需下载的资源 ab_download_ = new AssetBundleDownloader(current_url_); ab_download_.Start(Common.PATH, download_files, new_resources_manifest); while (!ab_download_.IsDone) { UpdateCompleteValue(ab_download_.CompletedSize, ab_download_.TotalSize); yield return(0); } if (ab_download_.IsFailed) { Error(emErrorCode.DownloadAssetBundleFailed); yield break; } }
/// <summary> /// 加载粒度信息 /// </summary> void LoadGranularityInfo(bool show_details, Action <string, float> progress_report) { Dictionary <string, string> granularity_details_table = null; if (show_details) { granularity_details_table = new Dictionary <string, string>(16384); } Dictionary <string, int> granularity_table = new Dictionary <string, int>(16384); //载入ResourcesManifest文件 ResourcesManifest resoureces_manifest = new ResourcesManifest(); resoureces_manifest.Load(EditorCommon.RESOURCES_MANIFEST_FILE_PATH); if (resoureces_manifest.Data.AssetBundles == null || resoureces_manifest.Data.AssetBundles.Count == 0) { return; } //载入AssetBunbleManifest string full_name = EditorCommon.MAIN_MANIFEST_FILE_PATH; AssetBundleManifest manifest = Common.LoadMainManifestByPath(full_name); if (manifest == null) { return; } var all_asset_bundle_names = manifest.GetAllAssetBundles(); //遍历AssetBundle,并载入所有AssetBundle float count = all_asset_bundle_names.Length; float current = 0; Dictionary <string, AssetBundle> all_ab = new Dictionary <string, AssetBundle>(all_asset_bundle_names.Length); foreach (var ab_name in all_asset_bundle_names) { if (progress_report != null) { progress_report("正在加载 " + ab_name, ++current / count); } AssetBundle ab = EditorCommon.LoadAssetBundleFromName(ab_name); all_ab.Add(ab_name, ab); } //遍历所有ab包,计算粒度 HashSet <string> result = new HashSet <string>(); HashSet <string> dep_asset_names = new HashSet <string>(); count = all_ab.Count; current = 0; foreach (var ab in all_ab) { string ab_name = ab.Key; AssetBundle assetbundle = ab.Value; if (progress_report != null) { progress_report("正在分析 " + ab_name, ++current / count); } //获得所有的AssetBundle依赖 string[] dep_ab_names = manifest.GetAllDependencies(ab_name); //获得所有依赖的AssetBundle的Asset dep_asset_names.Clear(); foreach (var dep_name in dep_ab_names) { AssetBundle dep_ab = null; if (all_ab.TryGetValue(dep_name, out dep_ab)) { string[] asset_names = dep_ab.GetAllAssetNames(); for (int i = 0; i < asset_names.Length; ++i) { dep_asset_names.Add(asset_names[i]); } } } //搜寻所有有效的资源 result.Clear(); List <string> assets = new List <string>(assetbundle.GetAllAssetNames()); SearchValidAsset(assets, dep_asset_names, ref result); //设置粒度值 foreach (var name in result) { if (granularity_table.ContainsKey(name)) { granularity_table[name] = granularity_table[name] + 1; } else { granularity_table.Add(name, 1); } if (granularity_details_table != null) { if (!granularity_details_table.ContainsKey(name)) { granularity_details_table.Add(name, ""); } granularity_details_table[name] = granularity_details_table[name] + ab_name + "\n"; } } result.Clear(); } //卸载所有AssetBundle foreach (var ab in all_ab) { ab.Value.Unload(true); } all_ab.Clear(); //刷新UI数据 string path = asset_bundle_build_.Data.BuildStartLocalPath.ToLower(); AssetNodeGroup group = gui_multi_select_.Group as AssetNodeGroup; current = 0; count = asset_bundle_build_.Data.Assets.Root.Count(); RefreshGranularity(granularity_table, granularity_details_table, path, group.Root, (name) => { if (progress_report != null) { progress_report("正在刷新 " + name, ++current / count); } }); }
/// <summary> /// 更新AssetBundle /// </summary> IEnumerator UpdatingUpdateAssetBundle() { if (ErrorCode != emErrorCode.None) { yield break; } UpdateCompleteValue(0f, 0f); //载入新的ResourcesManifest ResourcesManifest old_resource_manifest = AssetBundleManager.Instance.ResManifest; string file = Common.UPDATER_CACHE_PATH + "/" + Common.RESOURCES_MANIFEST_FILE_NAME; ResourcesManifest new_resources_manifest = Common.LoadResourcesManifestByPath(file); if (new_resources_manifest == null) { Error(emErrorCode.LoadNewResourcesManiFestFailed , "Can't load new verion ResourcesManifest!"); yield break; } //载入MainManifest AssetBundleManifest manifest = AssetBundleManager.Instance.MainManifest; file = Common.UPDATER_CACHE_PATH + "/" + Common.MAIN_MANIFEST_FILE_NAME; AssetBundleManifest new_manifest = Common.LoadMainManifestByPath(file); if (new_manifest == null) { Error(emErrorCode.LoadNewMainManifestFailed , "Can't find new version MainManifest!"); yield break; } //获取需下载的资源列表与删除的资源的列表 List <string> download_files = new List <string>(); List <string> delete_files = new List <string>(); ComparisonUtils.CompareAndCalcDifferenceFiles(ref download_files, ref delete_files , manifest, new_manifest , old_resource_manifest, new_resources_manifest , ComparisonUtils.emCompareMode.All); // 进度控制 float totalProgress = delete_files.Count + download_files.Count; float currentProgress = 0; //载入下载缓存数据, 过滤缓存中已下载的文件 DownloadCache download_cache = new DownloadCache(); download_cache.Load(Common.DOWNLOADCACHE_FILE_PATH); if (!download_cache.HasData()) { download_cache = null; } if (download_cache != null) { var cache_itr = download_cache.Data.AssetBundles.GetEnumerator(); while (cache_itr.MoveNext()) { DownloadCacheData.AssetBundle elem = cache_itr.Current.Value; string name = elem.AssetBundleName; string full_name = Common.GetFileFullName(name); if (File.Exists(full_name)) { string cache_hash = elem.Hash; string new_hash = new_manifest.GetAssetBundleHash(name).ToString(); if (!string.IsNullOrEmpty(cache_hash) && cache_hash.CompareTo(new_hash) == 0) { download_files.Remove(name); ++currentProgress; UpdateCompleteValue(currentProgress, totalProgress); yield return(null); } } } } //删除已废弃的文件 if (delete_files.Count > 0) { for (int i = 0; i < delete_files.Count; ++i) { string full_name = Common.GetFileFullName(delete_files[i]); if (File.Exists(full_name)) { File.Delete(full_name); ++currentProgress; UpdateCompleteValue(currentProgress, totalProgress); yield return(null); } } } //更新所有需下载的资源 ab_download_ = new AssetBundleDownloader(current_url_); ab_download_.Start(Common.PATH, download_files, new_resources_manifest); while (!ab_download_.IsDone) { UpdateCompleteValue(currentProgress + ab_download_.CompleteDownloadList.Count, totalProgress); yield return(null); } if (ab_download_.IsFailed) { Error(ab_download_.ErrorCode); yield break; } }