/// <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> IEnumerator StartDownloadPack() { if (ErrorCode != emErrorCode.None) { yield break; } UpdateCompleteValue(0f, 0f); if (packages_name_ == null) { Error(emErrorCode.InvalidPackageName); yield break; } //收集所有需要下载的AssetBundle List <string> ab_list = new List <string>(); for (int i = 0; i < packages_name_.Count; ++i) { string pack_name = packages_name_[i]; List <string> list = AssetBundleManager.Instance.FindAllAssetBundleFilesNameByPackage(pack_name); ab_list.AddRange(list); } if (ab_list == null) { Error(emErrorCode.NotFindAssetBundle); yield break; } //过滤已下载的资源 ab_list.RemoveAll((assetbundle_name) => { return(File.Exists(Common.GetFileFullName(assetbundle_name))); }); if (ab_list.Count == 0) { yield break; } //载入资源信息描述文件 ResourcesManifest resources_manifest = AssetBundleManager.Instance.ResourcesManifest; //开始下载 ab_download_ = new AssetBundleDownloader(current_url_); ab_download_.Start(Common.PATH, ab_list, resources_manifest); while (!ab_download_.IsDone) { UpdateCompleteValue(ab_download_.CompletedSize, ab_download_.TotalSize); yield return(null); } if (ab_download_.IsFailed) { Error(emErrorCode.DownloadAssetBundleFailed); yield break; } ab_download_ = null; yield return(null); }
/// <summary> /// 载入ResourcesManifest /// </summary> public static ResourcesManifest LoadResourcesManifestByPath(string full_name) { var result = new ResourcesManifest(); result.Load(full_name); return(result); }
/// <summary> /// 开始下载 /// </summary> public bool Start(string root , List <string> assetbundles , ResourcesManifest resources_manifest) { Abort(); if (resources_manifest == null) { Error(emErrorCode.ParameterError); return(false); } if (assetbundles == null || assetbundles.Count == 0) { IsDone = true; return(true); } IsDone = false; ErrorCode = emErrorCode.None; Root = root; resources_manifest_ = resources_manifest; UncompleteDownloadList = assetbundles; CompleteDownloadList.Clear(); FailedDownloadList.Clear(); //统计下载数据 TotalSize = 0; CompletedSize = 0; for (int i = 0; i < UncompleteDownloadList.Count; ++i) { var ab = resources_manifest_.Find(UncompleteDownloadList[i]); if (ab != null) { if (ab.IsCompress) { TotalSize += ab.CompressSize; } else { TotalSize += ab.Size; } } } //开始下载 for (int i = 0; i < System.Net.ServicePointManager.DefaultConnectionLimit; ++i) { HttpAsyDownload d = new HttpAsyDownload(URL); downloads_.Add(d); var assetbundlename = GetImcomplete(); if (!string.IsNullOrEmpty(assetbundlename)) { Download(downloads_[i], assetbundlename); } } return(true); }
/// <summary> /// 初始化 /// </summary> IEnumerator Preprocess() { //创建资源根目录 if (!Directory.Exists(Common.PATH)) { Directory.CreateDirectory(Common.PATH); } //判断主资源文件是否存在,不存在则拷贝备份资源至资源根目录 bool do_initial_copy = false; string resources_manifest_file = Common.GetFileFullName(Common.RESOURCES_MANIFEST_FILE_NAME); if (!File.Exists(resources_manifest_file)) { do_initial_copy = true; } else { // 拷贝安装包初始化目录中的ResourcesManifest,并判断是否重新拷贝初始化目录下的所有文件 string full_name = Common.GetFileFullName(Common.RESOURCES_MANIFEST_FILE_NAME); string initial_full_name = Common.GetInitialFileFullName(Common.RESOURCES_MANIFEST_FILE_NAME); string cache_full_name = Common.GetCacheFileFullName(Common.RESOURCES_MANIFEST_FILE_NAME); yield return(Common.StartCopyFile(initial_full_name, cache_full_name)); //判断安装包初始目录是否完整 ResourcesManifest initial = Common.LoadResourcesManifestByPath(cache_full_name); if (initial == null) { Error(emErrorCode.PreprocessError , "Initial path don't contains " + Common.RESOURCES_MANIFEST_FILE_NAME + "!"); yield break; } ResourcesManifest current = Common.LoadResourcesManifestByPath(full_name); if (current == null) { do_initial_copy = true; } else if (current.Data.Version < initial.Data.Version) { do_initial_copy = true; } //删除缓存中的文件 if (File.Exists(cache_full_name)) { File.Delete(cache_full_name); } } if (do_initial_copy) { yield return(CopyAllInitialFiles()); } PreprocessFinished(); }
/// <summary> /// 载入数据 /// </summary> private bool LoadData() { Manifest = new ResourcesManifest(); bool result = Manifest.Load(EditorCommon.RESOURCES_MANIFEST_FILE_PATH); Build(); return(result); }
/// <summary> /// 开始下载 /// </summary> public bool Start(string root , string assetbundlename , ResourcesManifest resources_manifest) { List <string> list = new List <string>(); list.Add(assetbundlename); return(Start(root, list, resources_manifest)); }
/// <summary> /// 获得包含某个资源的所有AssetBundle /// </summary> public string[] FindAllAssetBundleNameByAsset(string asset) { if (!IsReady) { return(null); } if (ResourcesManifest == null) { return(null); } return(ResourcesManifest.GetAllAssetBundleName(asset)); }
/// <summary> /// 获得一个场景的包名 /// </summary> public string FindAssetBundleNameByScene(string scene_name) { if (!IsReady) { return(null); } if (ResourcesManifest == null) { return(null); } return(ResourcesManifest.GetAssetBundleNameBySceneLevelName(scene_name)); }
/// <summary> /// 加载AssetBundle /// </summary> AssetBundle LoadAssetBundle(string assetbundlename) { if (assetbundlename == null) { return(null); } if (MainManifest == null) { return(null); } AssetBundle ab = null; if (assetbundle_permanent_.ContainsKey(assetbundlename)) { ab = assetbundle_permanent_[assetbundlename]; } else if (assetbundle_cache_.ContainsKey(assetbundlename)) { ab = assetbundle_cache_[assetbundlename]; } else if (assetbundle_temporary_.ContainsKey(assetbundlename)) { ab = assetbundle_temporary_[assetbundlename]; } else { string assetbundle_path = Common.PATH + "/" + assetbundlename; if (System.IO.File.Exists(assetbundle_path)) { ab = AssetBundle.LoadFromFile(assetbundle_path); //根据AssetBundleDescribe分别存放AssetBundle bool permanent = ResourcesManifest.IsPermanent(assetbundlename); if (permanent) { assetbundle_permanent_.Add(assetbundlename, ab); } else { assetbundle_temporary_.Add(assetbundlename, ab); } } } return(ab); }
/// <summary> /// 开始下载 /// </summary> public bool Start(string root , List <string> assetbundles , ResourcesManifest resources_manifest) { Abort(); if (resources_manifest == null) { IsDone = true; ErrorCode = emErrorCode.ParameterError; return(false); } InitializeDownload(root, assetbundles, resources_manifest); UpdateState(); DownloadAll(); return(true); }
/// <summary> /// 载入数据 /// </summary> public bool LoadData(ResourcesManifest manifest = null) { bool result = false; if (manifest == null) { Manifest = new ResourcesManifest(); result = Manifest.Load(EditorCommon.RESOURCES_MANIFEST_FILE_PATH); } else { Manifest = manifest; result = true; } Build(); return(result); }
/// <summary> /// 执行已做的修改 /// </summary> void ExecuteModified() { ResourcesManifest old_resources_manifest = new ResourcesManifest(); old_resources_manifest.Load(EditorCommon.RESOURCES_MANIFEST_FILE_PATH); //压缩AB包 bool compress = BuildAssetBundle.CompressAssetBundles(old_resources_manifest , Manifest); //保存数据 bool save = compress ? SaveData() : false; //拷贝资源 bool copy = save ? BuildAssetBundle.CopyNativeAssetBundleToStreamingAssets(Manifest) : false; bool succeed = compress && copy && save; if (succeed) { //同步数据 if (AssetBundleBuildWindow.Instance != null) { AssetBundleBuildWindow.Instance.SyncConfigForm(Manifest.Data); } else { AssetBundleBuild buildData = new AssetBundleBuild(); buildData.Load(EditorCommon.ASSETBUNDLE_BUILD_RULE_FILE_PATH); buildData.SyncConfigFrom(Manifest.Data); buildData.Save(EditorCommon.ASSETBUNDLE_BUILD_RULE_FILE_PATH); } } string title = "执行配置AssetBundle" + (succeed ? "成功" : "失败"); string compress_desc = "压缩资源 - " + (compress ? "成功" : "失败"); string save_desc = "保存配置文件 - " + (save ? "成功" : "失败"); string copy_desc = "拷贝初始资源至安装包目录 - " + (copy ? "成功" : "失败"); string desc = compress_desc + "\n" + save_desc + "\n" + copy_desc + "\n\n"; EditorUtility.DisplayDialog(title, desc, "确认"); }
/// <summary> /// 执行已做的修改 /// </summary> void ExecuteModified() { ResourcesManifest old_resources_manifest = new ResourcesManifest(); old_resources_manifest.Load(EditorCommon.RESOURCES_MANIFEST_FILE_PATH); bool compress = BuildAssetBundle.CompressAssetBundles(old_resources_manifest , ref Manifest); bool save = compress ? SaveData() : false; bool copy = save ? BuildAssetBundle.CopyNativeAssetBundleToStreamingAssets(Manifest) : false; bool succeed = compress && copy && save; string title = "执行配置AssetBundle" + (succeed ? "成功" : "失败"); string compress_desc = "压缩资源 - " + (compress ? "成功" : "失败"); string save_desc = "保存配置文件 - " + (save ? "成功" : "失败"); string copy_desc = "拷贝初始资源至安装包目录 - " + (copy ? "成功" : "失败"); string desc = compress_desc + "\n" + save_desc + "\n" + copy_desc + "\n\n"; EditorUtility.DisplayDialog(title, desc, "确认"); }
/// <summary> /// 拷贝初始目录所有文件 /// </summary> IEnumerator CopyAllInitialFiles() { //拷贝所有配置文件 for (int i = 0; i < Common.MAIN_CONFIG_NAME_ARRAY.Length; ++i) { yield return(Common.StartCopyInitialFile(Common.MAIN_CONFIG_NAME_ARRAY[i])); } //拷贝AssetBundle文件 ResourcesManifest resources_manifest = Common.LoadResourcesManifest(); if (resources_manifest == null) { Debug.LogWarning("Can't load ResourcesManifest file!"); yield break; } var itr = resources_manifest.Data.AssetBundles.GetEnumerator(); while (itr.MoveNext()) { if (itr.Current.Value.IsNative) { string assetbundlename = itr.Current.Value.AssetBundleName; string dest = Common.GetFileFullName(assetbundlename); //保证路径存在 string directory = Path.GetDirectoryName(dest); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } //拷贝数据 yield return(Common.StartCopyInitialFile(assetbundlename)); } } itr.Dispose(); }
/// <summary> /// 比较本地数据,获得需要修复的资源文件列表 /// </summary> public static void CompareAndCalcRecoverFiles(ref List <string> recover_files , ResourcesManifest resourcesmanifest) { if (resourcesmanifest == null) { return; } var itr = resourcesmanifest.Data.AssetBundles.GetEnumerator(); while (itr.MoveNext()) { if (itr.Current.Value.IsNative) { string name = itr.Current.Value.AssetBundleName; string full_name = Common.GetFileFullName(name); if (!File.Exists(full_name)) { recover_files.Add(name); } } } }
/// <summary> /// 初始化下载信息 /// </summary> void InitializeDownload(string root , List <string> assetbundles , ResourcesManifest resources_manifest) { Root = root; ImcompleteDownloads = assetbundles; resources_manifest_ = resources_manifest; IsDone = false; ErrorCode = emErrorCode.None; CompleteDownloads.Clear(); FailedDownloads.Clear(); if (ImcompleteDownloads == null) { ImcompleteDownloads = new List <string>(); } //统计数据 TotalSize = 0; CompletedSize = 0; for (int i = 0; i < ImcompleteDownloads.Count; ++i) { var ab = resources_manifest_.Find(ImcompleteDownloads[i]); if (ab != null) { if (ab.IsCompress) { TotalSize += ab.CompressSize; } else { TotalSize += ab.Size; } } } }
/// <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> /// 压缩AssetBundle /// </summary> public static bool CompressAssetBundles(ResourcesManifest old_resources_manifest , ref ResourcesManifest resources_manifest) { if (resources_manifest == null) { return(false); } // 通过记录新旧版本中压缩标记 // 判定资源是否需要压缩、删除压缩包 Dictionary <string, int> dic = new Dictionary <string, int>(); int old_version_bit = 0x1; // 旧版本中压缩 int new_version_bit = 0x2; // 新版本中压缩 var itr = old_resources_manifest.Data.AssetBundles.GetEnumerator(); while (itr.MoveNext()) { if (itr.Current.Value.IsCompress) { string name = itr.Current.Value.AssetBundleName; if (!dic.ContainsKey(name)) { dic.Add(name, old_version_bit); } else { dic[name] |= old_version_bit; } } } itr = resources_manifest.Data.AssetBundles.GetEnumerator(); while (itr.MoveNext()) { if (itr.Current.Value.IsCompress) { string name = itr.Current.Value.AssetBundleName; if (!dic.ContainsKey(name)) { dic.Add(name, new_version_bit); } else { dic[name] |= new_version_bit; } } } float current = 0f; float total = resources_manifest.Data.AssetBundles.Count; var itr1 = dic.GetEnumerator(); while (itr1.MoveNext()) { string name = itr1.Current.Key; int mask = itr1.Current.Value; //过滤主AssetBundle文件 if (name == Common.MAIN_MANIFEST_FILE_NAME) { continue; } string action; string file_name = EditorCommon.PATH + "/" + name; if ((mask & old_version_bit) > 0 && (mask & new_version_bit) == 0) { // 旧版本中存在,新版本不存在 // 删除压缩包 string compress_file = Compress.GetCompressFileName(file_name); File.Delete(compress_file); File.Delete(compress_file + Common.NATIVE_MANIFEST_EXTENSION); //重写ResourcesManifest数据 var ab = resources_manifest.Data.AssetBundles[name]; ab.CompressSize = 0; action = "Delete Compress"; } else if ((mask & new_version_bit) > 0) { //新版本中存在,压缩文件 Compress.CompressFile(file_name); //重写ResourcesManifest数据 var ab = resources_manifest.Data.AssetBundles[name]; ab.CompressSize = zcode.FileHelper.GetFileSize(Compress.GetCompressFileName(file_name)); action = "Compress"; } else { action = "Ignore"; } //更新进度条 if (ShowProgressBar("", action + " " + name, current / total)) { EditorUtility.ClearProgressBar(); return(false); } } EditorUtility.ClearProgressBar(); return(true); }
/// <summary> /// 根据AssetBundle导出ResourcesManifest文件 /// </summary> public static void ExportResourcesManifestFile(AssetBundleManifest manifest) { ResourcesManifest info = new ResourcesManifest(); //读取所有AssetBundle string root_dir = EditorCommon.PATH + "/"; List <string> scenes = new List <string>(); if (manifest != null) { //读取主AssetBundle ResourcesManifestData.AssetBundle desc = new ResourcesManifestData.AssetBundle(); desc.AssetBundleName = Common.MAIN_MANIFEST_FILE_NAME; desc.Size = zcode.FileHelper.GetFileSize(root_dir + Common.MAIN_MANIFEST_FILE_NAME); info.Data.AssetBundles.Add(Common.MAIN_MANIFEST_FILE_NAME, desc); //读取其它AssetBundle foreach (var name in manifest.GetAllAssetBundles()) { desc = new ResourcesManifestData.AssetBundle(); desc.AssetBundleName = name; desc.Size = zcode.FileHelper.GetFileSize(root_dir + name); AssetBundle ab = AssetBundle.LoadFromFile(root_dir + name); foreach (var asset in ab.GetAllAssetNames()) { desc.Assets.Add(asset); } foreach (var scene in ab.GetAllScenePaths()) { desc.Scenes.Add(scene); scenes.Add(scene); } ab.Unload(false); info.Data.AssetBundles.Add(name, desc); } } //读取所有Scene信息 for (int i = 0; i < scenes.Count; ++i) { ResourcesManifestData.Scene scene_desc = new ResourcesManifestData.Scene(); scene_desc.SceneLevelName = Path.GetFileNameWithoutExtension(scenes[i]); scene_desc.ScenePath = scenes[i]; scene_desc.SceneConfigPath = SceneConfig.GetSceneConfigPath(scenes[i]); info.Data.Scenes.Add(scene_desc.SceneLevelName, scene_desc); } //读取旧的ResourcesInfo,同步其它额外的数据 ResourcesManifest old_info = new ResourcesManifest(); old_info.Load(EditorCommon.RESOURCES_MANIFEST_FILE_PATH); if (old_info.Data != null && old_info.Data.AssetBundles.Count > 0) { foreach (var desc in old_info.Data.AssetBundles.Values) { if (info.Data.AssetBundles.ContainsKey(desc.AssetBundleName)) { info.Data.AssetBundles[desc.AssetBundleName].IsNative = desc.IsNative; info.Data.AssetBundles[desc.AssetBundleName].IsPermanent = desc.IsPermanent; } } } //保存ResourcesInfo info.Save(EditorCommon.RESOURCES_MANIFEST_FILE_PATH); AssetDatabase.Refresh(); }
/// <summary> /// 拷贝本地AssetBunle至StreamingAssets目录 /// </summary> public static bool CopyNativeAssetBundleToStreamingAssets(ResourcesManifest resources_manifest) { if (resources_manifest == null) { return(false); } //清空本地资源目录 if (ShowProgressBar("", "清空本地资源目录", 0f)) { EditorUtility.ClearProgressBar(); return(false); } if (!Directory.Exists(Common.INITIAL_PATH)) { Directory.CreateDirectory(Common.INITIAL_PATH); } else { zcode.FileHelper.DeleteAllChild(Common.INITIAL_PATH , FileAttributes.Hidden | FileAttributes.System); } //拷贝所有配置文件 for (int i = 0; i < Common.MAIN_CONFIG_NAME_ARRAY.Length; ++i) { string file = Common.MAIN_CONFIG_NAME_ARRAY[i]; string src_file_name = EditorCommon.PATH + "/" + file; string dest_file_name = Common.INITIAL_PATH + "/" + file; float progress = (float)(i + 1) / (float)Common.MAIN_CONFIG_NAME_ARRAY.Length; if (ShowProgressBar("", "Copy " + file, progress)) { EditorUtility.ClearProgressBar(); return(false); } zcode.FileHelper.CopyFile(src_file_name, dest_file_name, true); } //拷贝AssetBundle文件 float current = 0f; float total = resources_manifest.Data.AssetBundles.Count; foreach (var desc in resources_manifest.Data.AssetBundles.Values) { current += 1f; //过滤主AssetBundle文件 if (desc.AssetBundleName == Common.MAIN_MANIFEST_FILE_NAME) { continue; } if (desc.IsNative) { zcode.FileHelper.CopyFile(EditorCommon.PATH + "/" + desc.AssetBundleName , Common.INITIAL_PATH + "/" + desc.AssetBundleName, true); } //更新进度条 if (ShowProgressBar("", "Copy " + desc.AssetBundleName, current / total)) { EditorUtility.ClearProgressBar(); return(false); } } EditorUtility.ClearProgressBar(); AssetDatabase.Refresh(); return(true); }
/// <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; } }
/// <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> public static void CompareAndCalcDifferenceFiles(ref List <string> download_files , ref List <string> delete_files , AssetBundleManifest old_manifest , AssetBundleManifest new_manifest , ResourcesManifest old_resourcesmanifest , ResourcesManifest new_resourcesmanifest , emCompareMode compareMode) { if (download_files == null) { return; } download_files.Clear(); if (delete_files == null) { return; } delete_files.Clear(); if (old_manifest == null) { return; } if (new_manifest == null) { return; } if (new_resourcesmanifest == null) { return; } //采用位标记的方式判断资源 //位标记: 0: 存在旧资源中 1: 存在新资源中 2:旧的本地资源 3:新的本地资源 int old_version_bit = 0x1; // 存在旧版本中 int new_version_bit = 0x2; // 存在新版本中 int old_version_native_bit = 0x4; // 旧的本地资源 int new_version_native_bit = 0x8; // 新的本地资源 Dictionary <string, int> temp_dic = new Dictionary <string, int>(); //标记旧资源 string[] all_assetbundle = old_manifest.GetAllAssetBundles(); for (int i = 0; i < all_assetbundle.Length; ++i) { string name = all_assetbundle[i]; _SetDictionaryBit(ref temp_dic, name, old_version_bit); } //标记新资源 string[] new_all_assetbundle = new_manifest.GetAllAssetBundles(); for (int i = 0; i < new_all_assetbundle.Length; ++i) { string name = new_all_assetbundle[i]; _SetDictionaryBit(ref temp_dic, name, new_version_bit); } //标记旧的本地资源 if (old_resourcesmanifest.Data != null && old_resourcesmanifest.Data.AssetBundles != null) { var resource_manifest_itr = old_resourcesmanifest.Data.AssetBundles.GetEnumerator(); while (resource_manifest_itr.MoveNext()) { if (resource_manifest_itr.Current.Value.IsNative) { string name = resource_manifest_itr.Current.Value.AssetBundleName; string full_name = Common.GetFileFullName(Common.RESOURCES_MANIFEST_FILE_NAME); if (File.Exists(full_name)) { _SetDictionaryBit(ref temp_dic, name, old_version_native_bit); } } } } //标记新的本地资源 if (new_resourcesmanifest.Data != null && new_resourcesmanifest.Data.AssetBundles != null) { var resource_manifest_itr = new_resourcesmanifest.Data.AssetBundles.GetEnumerator(); while (resource_manifest_itr.MoveNext()) { if (resource_manifest_itr.Current.Value.IsNative) { string name = resource_manifest_itr.Current.Value.AssetBundleName; _SetDictionaryBit(ref temp_dic, name, new_version_native_bit); } } } //获得对应需操作的文件名, 优先级: both > add > delete int both_bit = old_version_bit | new_version_bit; // 二个版本资源都存在 List <string> add_files = new List <string>(); List <string> both_files = new List <string>(); var itr = temp_dic.GetEnumerator(); while (itr.MoveNext()) { string name = itr.Current.Key; int mask = itr.Current.Value; //add: 第2位未标记,且第3位被标记的 if ((mask & new_version_native_bit) == new_version_native_bit && (mask & old_version_native_bit) == 0) { add_files.Add(name); } //both: 第0位与第1位都被标记的 else if ((mask & both_bit) == both_bit) { // 如果为emCompareMode.OnlyInitial比较方式,则需确定是否为本地资源 if (compareMode == emCompareMode.OnlyInitial) { if ((mask & new_version_native_bit) == new_version_native_bit) { both_files.Add(name); } } else { both_files.Add(name); } } //delete: 第0位被标记的 else if ((mask & old_version_bit) == old_version_bit) { // 且必须本地存在 string full_name = Common.GetFileFullName(name); if (File.Exists(full_name)) { delete_files.Add(name); } } } itr.Dispose(); //记录需下载的文件 { //加入新增的文件 download_files.AddRange(add_files); //比较所有同时存在的文件,判断哪些需要更新 for (int i = 0; i < both_files.Count; ++i) { string name = both_files[i]; string full_name = Common.GetFileFullName(name); if (File.Exists(full_name)) { //判断哈希值是否相等 string old_hash = old_manifest.GetAssetBundleHash(name).ToString(); string new_hash = new_manifest.GetAssetBundleHash(name).ToString(); if (old_hash.CompareTo(new_hash) == 0) { continue; } download_files.Add(name); } } } }
/// <summary> /// 比较AssetBundle差异,获得下载列表与删除列表 /// </summary> static void CompareAssetBundleDifference(ref List <string> download_files, ref List <string> delete_files, AssetBundleManifest old_manifest, AssetBundleManifest new_manifest, ResourcesManifest old_resourcesmanifest, ResourcesManifest new_resourcesmanifest) { if (download_files != null) { download_files.Clear(); } if (delete_files != null) { delete_files.Clear(); } if (old_manifest == null) { return; } if (new_manifest == null) { return; } if (new_resourcesmanifest == null) { return; } //采用位标记的方式判断资源 //位标记: 0: 存在旧资源中 1: 存在新资源中 2:本地资源标记 int old_version_bit = 0x1; // 存在旧资源中 int new_version_bit = 0x2; // 存在新资源中 int old_version_native_bit = 0x4; // 旧的本地资源 int new_version_native_bit = 0x8; // 新的本地资源 Dictionary <string, int> temp_dic = new Dictionary <string, int>(); //标记旧资源 string[] all_assetbundle = old_manifest.GetAllAssetBundles(); for (int i = 0; i < all_assetbundle.Length; ++i) { string name = all_assetbundle[i]; _SetDictionaryBit(ref temp_dic, name, old_version_bit); } //标记新资源 string[] new_all_assetbundle = new_manifest.GetAllAssetBundles(); for (int i = 0; i < new_all_assetbundle.Length; ++i) { string name = new_all_assetbundle[i]; _SetDictionaryBit(ref temp_dic, name, new_version_bit); } //标记旧的本地资源 if (old_resourcesmanifest.Data != null && old_resourcesmanifest.Data.AssetBundles != null) { var resource_manifest_itr = old_resourcesmanifest.Data.AssetBundles.GetEnumerator(); while (resource_manifest_itr.MoveNext()) { if (resource_manifest_itr.Current.Value.IsNative) { string name = resource_manifest_itr.Current.Value.AssetBundleName; _SetDictionaryBit(ref temp_dic, name, old_version_native_bit); } } } //标记新的本地资源 if (new_resourcesmanifest.Data != null && new_resourcesmanifest.Data.AssetBundles != null) { var resource_manifest_itr = new_resourcesmanifest.Data.AssetBundles.GetEnumerator(); while (resource_manifest_itr.MoveNext()) { if (resource_manifest_itr.Current.Value.IsNative) { string name = resource_manifest_itr.Current.Value.AssetBundleName; _SetDictionaryBit(ref temp_dic, name, new_version_native_bit); } } } //获得对应需操作的文件名, 优先级: both > add > delete //both: 第0位与第1位都被标记的 //delete: 仅第0位被标记的 //add: 第2位未标记,且第3位被标记的 int both_bit = old_version_bit | new_version_bit; // 二个版本资源都存在 List <string> add_files = new List <string>(); List <string> both_files = new List <string>(); var itr = temp_dic.GetEnumerator(); while (itr.MoveNext()) { string name = itr.Current.Key; int mask = itr.Current.Value; if ((mask & new_version_native_bit) == new_version_native_bit && (mask & old_version_native_bit) == 0) { add_files.Add(name); } else if ((mask & both_bit) == both_bit) { both_files.Add(name); } else if ((mask & old_version_bit) == old_version_bit) { delete_files.Add(name); } } itr.Dispose(); //载入下载缓存数据 DownloadCache download_cache = new DownloadCache(); download_cache.Load(Common.DOWNLOADCACHE_FILE_PATH); if (!download_cache.HasData()) { download_cache = null; } //记录需下载的文件 { //加入新增的文件 download_files.AddRange(add_files); //比较所有同时存在的文件,判断哪些需要更新 for (int i = 0; i < both_files.Count; ++i) { string name = both_files[i]; string full_name = Common.GetFileFullName(name); if (File.Exists(full_name)) { //判断哈希值是否相等 string old_hash = old_manifest.GetAssetBundleHash(name).ToString(); string new_hash = new_manifest.GetAssetBundleHash(name).ToString(); if (old_hash.CompareTo(new_hash) == 0) { continue; } download_files.Add(name); } } //过滤缓存中已下载的文件 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); } } } } } }
/// <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); }