private void CreateIPAExportOptionsPlist() { var ios = Module.UserConfig.Json.PlayerSettings.IOS; var eo = ios.IPAExportOptions; PlistDocument plist = new PlistDocument(); plist.root = new PlistElementDict(); plist.root.SetBoolean("compileBitcode", eo.CompileBitcode); plist.root.SetString("destination", eo.Destination); plist.root.SetString("method", eo.Method); var provisioningProfiles = plist.root.CreateDict("provisioningProfiles"); provisioningProfiles.SetString(ios.BundleID, ios.ProfileID); plist.root.SetString("signingCertificate", eo.SigningCertificate); plist.root.SetString("signingStyle", eo.SigningStyle); plist.root.SetBoolean("stripSwiftSymbols", eo.StripSwiftSymbols); plist.root.SetString("teamID", ios.TeamID); plist.root.SetString("thinning", eo.Thinning); string tagsPath = Path.Combine(Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(Module.ModuleStateConfig.Json.CurrentTag)); string ipaFolderPath = Path.Combine(tagsPath, "IPA"); Directory.CreateDirectory(ipaFolderPath); plist.WriteToFile(Path.Combine(ipaFolderPath, "ExportOptions.plist")); }
private void XcodeBuild() { string workPath = Path.Combine(Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(Module.ModuleStateConfig.Json.CurrentTag)); message = errorMessage = ""; Module.DisplayProgressBar("Start Xcode Build...", 0, true); using (var xcodeBuildLogWriter = new StreamWriter(Path.Combine(CommonModule.CommonConfig.CurrentLogFolderPath, "XcodeBuild.log")) { AutoFlush = true }) { Process p = SVNUpdate.Runner.ExcuteCommand("/bin/bash", EBPUtility.Quote(Path.Combine(Module.ModuleConfig.ModuleRootPath, "Shells/XcodeBuild.sh")) + " " + EBPUtility.Quote(workPath) + " " + EBPUtility.Quote("Project/Unity-iPhone.xcodeproj"), (object sender, DataReceivedEventArgs e) => { message = e.Data; xcodeBuildLogWriter.WriteLine(message); }, OnErrorReceived, null); int progress = 0; while (!p.HasExited) { Module.DisplayProgressBar("Xcode Building...", message, (float)(progress++ % 1000) / 1000); System.Threading.Thread.Sleep(100); } if (p.ExitCode != 0) { throw new EBPException("XcodeBuild Shell Error: " + errorMessage); } } Module.DisplayProgressBar("Xcode Build", "Finish!", 1, true); }
protected override void RunProcess() { //清理无用Bundle项 List <AssetBundleBuild> cleanedBuilds = null; if (Module.ModuleStateConfig.Json.CleanUpBundles) { Module.DisplayProgressBar("开始清理无用Bundle项", 0, true); AssetPolice.Editor.Module policeModule = new AssetPolice.Editor.Module(); AssetPolice.Editor.Runner policeRunner = new AssetPolice.Editor.Runner(policeModule); policeModule.LoadConfigs(); policeModule.ModuleConfig.Json.OutputPath = CommonModule.CommonConfig.CurrentLogFolderPath; //Hack: 由于输出目录必须存在,所以临时这样设置 policeRunner.Run(); cleanedBuilds = policeRunner.GetCleanedBuilds(Module.UserConfig.Json, CommonModule.CommonConfig.CurrentLogFolderPath); } else { cleanedBuilds = Module.UserConfig.Json; } //准备参数 BuildTarget target = (BuildTarget)Enum.Parse(typeof(BuildTarget), Module.ModuleStateConfig.Json.CurrentTag[0], true); int optionsValue = Module.ModuleStateConfig.Json.CurrentBuildAssetBundleOptionsValue; int resourceVersion = Module.ModuleStateConfig.Json.ResourceVersion; string tagPath = Path.Combine(Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(Module.ModuleStateConfig.Json.CurrentTag)); //创建目录 Module.DisplayProgressBar("正在重建目录:" + tagPath, 0.3f, true); if (Directory.Exists(tagPath)) { Directory.Delete(tagPath, true); //清空目录 } string infoPath = Path.Combine(tagPath, "_Info"); string bundlesPath = Path.Combine(tagPath, "Bundles"); Directory.CreateDirectory(infoPath); Directory.CreateDirectory(bundlesPath); //创建json文件 Module.DisplayProgressBar("Creating Info Files...", 0.45f, true); File.WriteAllText(Path.Combine(infoPath, "BuildMap.json"), JsonConvert.SerializeObject(cleanedBuilds, Formatting.Indented)); File.WriteAllText(Path.Combine(infoPath, "Versions.json"), JsonConvert.SerializeObject(new Dictionary <string, int> { { "ResourceVersion", resourceVersion } }, Formatting.Indented)); //创建Map文件 //此处保留旧map文件的生成方式 AssetBundleManagement.ABExtractItemBuilder.BuildMapperFile(AssetBundleManagement.ABExtractItemBuilder.BuildAssetMapper(cleanedBuilds.ToArray()), Path.Combine(infoPath, "map")); //创建Bundles Module.DisplayProgressBar("Start Build AssetBundles...", 0.5f, true); var manifest = BuildPipeline.BuildAssetBundles(bundlesPath, cleanedBuilds.ToArray(), (BuildAssetBundleOptions)optionsValue, target); if (manifest == null) { throw new EBPException("BuildAssetBundles失败!详情请查看Console面板。"); } //重命名Bundles清单文件 Module.DisplayProgressBar("Renaming assetbundlemanifest...", 1f, true); RenameMainBundleManifest(bundlesPath); }
private void PrepareBuildOptions() { //准备BuildOptions BuildOptions buildOptions = (Module.ModuleStateConfig.Json.DevelopmentBuild ? BuildOptions.Development : BuildOptions.None) | (Module.ModuleStateConfig.Json.ConnectWithProfiler ? BuildOptions.ConnectWithProfiler : BuildOptions.None) | (Module.ModuleStateConfig.Json.AllowDebugging ? BuildOptions.AllowDebugging : BuildOptions.None) | (Module.UserConfig.Json.BuildSettings.CompressionMethod == UserConfig.BuildSettings.CompressionMethodEnum.LZ4 ? BuildOptions.CompressWithLz4 : BuildOptions.None) | (Module.UserConfig.Json.BuildSettings.CompressionMethod == UserConfig.BuildSettings.CompressionMethodEnum.LZ4HC ? BuildOptions.CompressWithLz4HC : BuildOptions.None); //设置路径和文件名 string tagsPath = Path.Combine(Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(Module.ModuleStateConfig.Json.CurrentTag)); string locationPath; string versionInfo = string.Format("{0}_{1}.{2}", PlayerSettings.productName, PlayerSettings.bundleVersion, PlayerSettings.Android.bundleVersionCode); switch (EditorUserBuildSettings.activeBuildTarget) { case BuildTarget.Android: locationPath = Path.Combine(tagsPath, versionInfo + ".apk"); break; case BuildTarget.iOS: locationPath = Path.Combine(tagsPath, "Project"); break; default: throw new EBPException("意外的平台:" + EditorUserBuildSettings.activeBuildTarget); } //获取场景 string[] scenes = EditorBuildSettingsScene.GetActiveSceneList(EditorBuildSettings.scenes).Take(2).ToArray(); //Hack: 只获取头两个场景 //构成BuildPlayerOptions BuildPlayerOptions = new BuildPlayerOptions { scenes = scenes, locationPathName = locationPath, target = EditorUserBuildSettings.activeBuildTarget, options = buildOptions }; }
private void ClickedApply() { G.Module.UserConfig.Json.Packages = GetPackageMap(); //从配置现场覆盖当前map try { CommonModule.ClearLogFolderPath(); G.Runner.Check(); } catch (EBPCheckFailedException e) { G.Module.DisplayDialog(e.Message); return; } if (!CheckAllPackageItem()) { return; } bool ensure = G.Module.DisplayDialog("确定应用当前配置?", "确定", "取消"); if (ensure) { try { G.Module.DisplayProgressBar("Build Packages", "Starting...", 0); double startTime = EditorApplication.timeSinceStartup; CommonModule.GenerateLogFolderPath(); G.Runner.Run(); TimeSpan time = TimeSpan.FromSeconds(EditorApplication.timeSinceStartup - startTime); if (G.Module.DisplayDialog("打包完成!用时:" + string.Format("{0}时 {1}分 {2}秒", time.Hours, time.Minutes, time.Seconds), "显示文件", "关闭")) { string firstPackagePath = Path.Combine(G.Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(G.Module.ModuleStateConfig.Json.CurrentTag)); EditorUtility.RevealInFinder(firstPackagePath); } } catch { G.Module.DisplayRunError(); } } }
public string GetBundleInfoFolderPath() { return(Path.Combine(ModuleConfig.BundleWorkFolderPath, EBPUtility.GetTagStr(ModuleStateConfig.Json.CurrentTag) + "/_Info")); }
private void ClickedApply() { G.Module.ModuleStateConfig.Json.CurrentUserConfigName = Path.GetFileName(AssetBundleManagement2.AssetBundleModel.BuildMapPath) + ".json"; //TODO: 覆盖当前map文件名,BundleMaster的特殊处理 G.Module.UserConfig.Json = G.g.mainTab.GetBuildMap_extension().ToList(); //从配置现场覆盖当前map try { CommonModule.ClearLogFolderPath(); G.Runner.Check(); } catch (EBPCheckFailedException e) { G.Module.DisplayDialog(e.Message); return; } //确认信息 BuildTarget target = (BuildTarget)Enum.Parse(typeof(BuildTarget), G.Module.ModuleStateConfig.Json.CurrentTag[0], true); int optionsValue = G.Module.ModuleStateConfig.Json.CurrentBuildAssetBundleOptionsValue; int resourceVersion = G.Module.ModuleStateConfig.Json.ResourceVersion; string tagPath = Path.Combine(G.Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(G.Module.ModuleStateConfig.Json.CurrentTag)); bool ensure = G.Module.DisplayDialog(string.Format("确定应用当前配置?\n\n" + "目标平台: {0}\n 输出路径: {1} \n Resources Version: {2} \n 参数: {3}", target, tagPath, resourceVersion, optionsValue), "确定", "取消"); //开始应用 if (ensure) { try { CommonModule.GenerateLogFolderPath(); G.Runner.Run(); G.Module.DisplayDialog("创建AssetBundles成功!"); } catch { G.Module.DisplayRunError(); } } }
public void OnGUI() { scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); if (creatingNewConfig == true && GUI.GetNameOfFocusedControl() != "InputField1") { creatingNewConfig = false; } //Root GUILayout.FlexibleSpace(); EBPEditorGUILayout.RootSettingLine(PlayerBuilder.G.Module, ChangeRootPath); GUILayout.FlexibleSpace(); //SVN Update EditorGUILayout.BeginHorizontal(); FrontIndicator(currentStep == Step.SVNUpdate, false, G.Module.SVNUpdateRunner.errorMessage); G.Module.SVNUpdateRunner.IsPartOfPipeline = GUILayout.Toggle(G.Module.SVNUpdateRunner.IsPartOfPipeline, "SVN Update", GUILayout.Width(200)) && G.Module.SVNUpdateRunner.Available; SVNInfo(); if (GUILayout.Button(refreshIcon, miniButtonOptions)) { RunSVNCheckProcess(); } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); GUILayout.FlexibleSpace(); //AssetPreprocessor EditorGUILayout.BeginHorizontal(); FrontIndicator(currentStep == Step.PreprocessAssets, G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.Applying, G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.ErrorMessage); G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.IsPartOfPipeline = EditorGUILayout.BeginToggleGroup( assetPreprocessorContent, G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.IsPartOfPipeline); EditorGUILayout.BeginHorizontal(); int index_new = EditorGUILayout.Popup(assetPreprocessorUserConfigSelectedIndex, assetPreprocessorUserConfigNames, dropdownOptions); if (assetPreprocessorUserConfigSelectedIndex != index_new) { assetPreprocessorUserConfigSelectedIndex = index_new; G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.CurrentUserConfigName = assetPreprocessorUserConfigNames[index_new] + ".json"; G.Module.AssetPreprocessorModule.LoadUserConfig(); return; } if (GUILayout.Button(settingGUIContent, miniButtonOptions)) { AssetPreprocessor.G.OverrideCurrentUserConfigName = G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.CurrentUserConfigName; if (AssetPreprocessor.G.g == null) { EditorWindow.GetWindow <AssetPreprocessor.Editor.AssetPreprocessorWindow>(); AssetPreprocessor.G.g.OnChangeCurrentUserConfig += Action_AssetPreprocessor_OnChangeCurrentConfig; AssetPreprocessor.G.g.OnChangeConfigList += Action_OnChangeConfigList; } else { EditorWindow.GetWindow <AssetPreprocessor.Editor.AssetPreprocessorWindow>(); } return; } GUILayout.Space(10); GUILayout.Label(G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.IsPartOfPipeline ? "<color=orange>→ " + EBPUtility.GetTagStr(G.Module.AssetPreprocessorModule.UserConfig.Json.Tags) + "</color>" : "<color=cyan>" + EBPUtility.GetTagStr(CommonModule.CommonConfig.Json.CurrentAssetTag) + "</color>", richTextLabel); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndToggleGroup(); EditorGUILayout.EndHorizontal(); GUILayout.FlexibleSpace(); //BundleManager EditorGUILayout.BeginHorizontal(); FrontIndicator(currentStep == Step.BuildBundles, G.Module.BundleManagerModule.ModuleStateConfig.Json.Applying, G.Module.BundleManagerModule.ModuleStateConfig.Json.ErrorMessage); G.Module.BundleManagerModule.ModuleStateConfig.Json.IsPartOfPipeline = EditorGUILayout.BeginToggleGroup( bundleManagerContent, G.Module.BundleManagerModule.ModuleStateConfig.Json.IsPartOfPipeline); EditorGUILayout.BeginHorizontal(); index_new = EditorGUILayout.Popup(bundleManagerUserConfigSelectedIndex, bundleManagerUserConfigNames, dropdownOptions); if (bundleManagerUserConfigSelectedIndex != index_new) { bundleManagerUserConfigSelectedIndex = index_new; G.Module.BundleManagerModule.ModuleStateConfig.Json.CurrentUserConfigName = bundleManagerUserConfigNames[index_new] + ".json"; return; } if (GUILayout.Button(settingGUIContent, miniButtonOptions)) { if (BundleManager.G.g == null) { EditorWindow.GetWindow <BundleManager.Editor.BundleManagerWindow>(); BundleManager.G.g.OnChangeConfigList += Action_OnChangeConfigList; } else { EditorWindow.GetWindow <BundleManager.Editor.BundleManagerWindow>(); } return; } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndToggleGroup(); GUILayout.Space(10); EditorGUILayout.LabelField("Resource Version:", labelOptions); int n = EditorGUILayout.IntField(G.Module.BundleManagerModule.ModuleStateConfig.Json.ResourceVersion, inputOptions); if (G.Module.BundleManagerModule.ModuleStateConfig.Json.ResourceVersion != n) { G.Module.BundleManagerModule.ModuleStateConfig.Json.ResourceVersion = n; } int selectedCompressionIndex_new = EditorGUILayout.Popup(selectedCompressionIndex, G.Module.BundleManagerModule.CompressionEnum, dropdownOptions2); if (selectedCompressionIndex_new != selectedCompressionIndex) { G.Module.BundleManagerModule.ModuleStateConfig.Json.CompressionOption = G.Module.BundleManagerModule.CompressionEnumMap[G.Module.BundleManagerModule.CompressionEnum[selectedCompressionIndex_new]]; selectedCompressionIndex = selectedCompressionIndex_new; return; } G.Module.BundleManagerModule.ModuleStateConfig.Json.CleanUpBundles = GUILayout.Toggle(G.Module.BundleManagerModule.ModuleStateConfig.Json.CleanUpBundles, "CleanUp"); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); GUILayout.FlexibleSpace(); //PackageManager EditorGUILayout.BeginHorizontal(); FrontIndicator(currentStep == Step.BuildPackages, G.Module.PackageManagerModule.ModuleStateConfig.Json.Applying, G.Module.PackageManagerModule.ModuleStateConfig.Json.ErrorMessage); G.Module.PackageManagerModule.ModuleStateConfig.Json.IsPartOfPipeline = EditorGUILayout.BeginToggleGroup( packageManagerContent, G.Module.PackageManagerModule.ModuleStateConfig.Json.IsPartOfPipeline); EditorGUILayout.BeginHorizontal(); index_new = EditorGUILayout.Popup(packageManagerUserConfigSelectedIndex, packageManagerUserConfigNames, dropdownOptions); if (packageManagerUserConfigSelectedIndex != index_new) { packageManagerUserConfigSelectedIndex = index_new; G.Module.PackageManagerModule.ModuleStateConfig.Json.CurrentUserConfigName = packageManagerUserConfigNames[index_new] + ".json"; return; } if (GUILayout.Button(settingGUIContent, miniButtonOptions)) { PackageManager.G.OverrideCurrentUserConfigName = G.Module.PackageManagerModule.ModuleStateConfig.Json.CurrentUserConfigName; if (PackageManager.G.g == null) { EditorWindow.GetWindow <PackageManager.Editor.PackageManagerWindow>(); PackageManager.G.g.OnChangeConfigList += Action_OnChangeConfigList; } else { EditorWindow.GetWindow <PackageManager.Editor.PackageManagerWindow>(); } return; } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndToggleGroup(); GUILayout.Space(10); EditorGUILayout.LabelField("Client Version:", labelOptions); string packageVersion_new = EditorGUILayout.TextField(G.Module.PackageManagerModule.ModuleStateConfig.Json.ClientVersion, inputOptions); if (G.Module.PackageManagerModule.ModuleStateConfig.Json.ClientVersion != packageVersion_new) { G.Module.PackageManagerModule.ModuleStateConfig.Json.ClientVersion = packageVersion_new; } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); GUILayout.FlexibleSpace(); //BuildPlayer EditorGUILayout.BeginHorizontal(); FrontIndicator(currentStep == Step.BuildPlayer || currentStep == Step.Prepare, G.Module.PlayerBuilderModule.ModuleStateConfig.Json.Applying, G.Module.PlayerBuilderModule.ModuleStateConfig.Json.ErrorMessage); G.Module.PlayerBuilderModule.ModuleStateConfig.Json.IsPartOfPipeline = EditorGUILayout.BeginToggleGroup( playerBuilderContent, G.Module.PlayerBuilderModule.ModuleStateConfig.Json.IsPartOfPipeline); EditorGUILayout.BeginHorizontal(); if (creatingNewConfig) { ShowInputField(); } else { if (ShowBuildSettingDropdown()) { return; } } if (GUILayout.Button(new GUIContent(EditorGUIUtility.FindTexture("ViewToolOrbit"), "查看该文件"), miniButtonOptions)) { ClickedShowConfigFile(); return; } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndToggleGroup(); GUILayout.Space(10); EditorGUILayout.LabelField("Build Number:", labelOptions); int buildNum = EditorGUILayout.IntField(G.Module.PlayerBuilderModule.ModuleStateConfig.Json.BuildNumber, inputOptions); if (G.Module.PlayerBuilderModule.ModuleStateConfig.Json.BuildNumber != buildNum) { G.Module.PlayerBuilderModule.ModuleStateConfig.Json.BuildNumber = buildNum; } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); GUILayout.FlexibleSpace(); EditorGUILayout.BeginHorizontal(); GUILayout.Space(30); if (GUILayout.Button(new GUIContent("New", "新建配置文件"), buttonOptions)) { ClickedNew(); return; } if (GUILayout.Button(new GUIContent("Save", "保存配置文件"), buttonOptions)) { ClickedSave(); return; } if (GUILayout.Button(new GUIContent("Revert", "重新载入配置文件"), buttonOptions)) { ClickedRevert(); return; } if (GUILayout.Button(new GUIContent("Apply", "应用下面的PlayerSettings(不包括宏定义)"), buttonOptions)) { ClickedApply(); return; } if (GUILayout.Button(new GUIContent("Fetch", "获取当前的PlayerSettings"), buttonOptions)) { FetchSettings(); return; } if (GUILayout.Button(new GUIContent("CopyDir", "自动拷贝目录并设置宏定义"), buttonOptions)) { if (PlayerBuilder.Editor.PlayerSettingsPanel.CopyNow(EditorUserBuildSettings.activeBuildTarget)) { G.Module.PlayerBuilderRunner.ApplyScriptDefines(EditorUserBuildSettings.activeBuildTarget); ToLuaMenu.ClearLuaWraps(); } return; } if (GUILayout.Button(new GUIContent("RevertDir", "自动恢复拷贝目录并恢复宏定义"), buttonOptions)) { if (PlayerBuilder.Editor.PlayerSettingsPanel.RevertNow()) { G.Module.PlayerBuilderRunner.ApplyScriptDefines(EditorUserBuildSettings.activeBuildTarget, true); ToLuaMenu.ClearLuaWraps(); } return; } GUILayout.FlexibleSpace(); //Run Button Color defaultColor = GUI.contentColor; GUI.contentColor = Color.green; if (PlayerBuilder.G.Module.StateConfigAvailable) { if (GUILayout.Button(new GUIContent("Run Pipeline"))) { ClickedRunPipeline(); return; } } else { if (GUILayout.Button(new GUIContent("Check", "检查所有勾选的模块配置"))) { ClickedCheckAll(); return; } } GUI.contentColor = defaultColor; EditorGUILayout.EndHorizontal(); EditorGUILayout.EndScrollView(); }
protected override void RunProcess() { //准备参数 bundlesFolderPath = Module.GetBundleFolderPath(); if (!Directory.Exists(bundlesFolderPath)) { throw new EBPException("Bundles目录不存:" + bundlesFolderPath); } string packagesFolderPath = Path.Combine(Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(Module.ModuleStateConfig.Json.CurrentTag) + "/" + Module.UserConfig.Json.PackageMode); int count = 0; int total = 0; float progress = 0; var packages = Module.UserConfig.Json.Packages; //清除不存在的Bundle Module.DisplayProgressBar("正在从Packages清单中清除不存在的Bundle", 0, true); notExistLogWriter = new StreamWriter(Path.Combine(CommonModule.CommonConfig.CurrentLogFolderPath, "NotExistBundlesWhenBuildPackage.log")); notExistLogWriter.WriteLine("Root: " + bundlesFolderPath + "\n"); cleanBundlesCount = 0; foreach (var package in packages) { package.Bundles.RemoveAll(IsNotExist); } notExistLogWriter.WriteLine("\ntotal:" + cleanBundlesCount); notExistLogWriter.Close(); //统计总数 foreach (var package in packages) { total += package.Bundles.Count; } int packagesCount = packages.Count; //TODO:构建map改进方法 //if (Configs.g.bundleTree.BundleBuildMap == null) //{ // throw new EBPException("BuildMap is null"); //} //string mapContent = JsonConvert.SerializeObject(BuildAsset2BundleMap(Configs.g.bundleTree.BundleBuildMap), Formatting.Indented); //重建目录 Module.DisplayProgressBar("正在重建" + Module.UserConfig.Json.PackageMode + "目录", packagesFolderPath, progress, true); progress += 0.01f; if (Directory.Exists(packagesFolderPath)) { Directory.Delete(packagesFolderPath, true); } Directory.CreateDirectory(packagesFolderPath); //设置路径 string platform = Module.ModuleStateConfig.Json.CurrentTag[0].ToLower(); string bundlesRootPathInPackage = "AssetBundles/" + platform + "/AssetBundles/"; string bundleVersionFilePathInPackage = "AssetBundles/" + platform + "/bundle_version"; string mapFilePathInPackage = "AssetBundles/" + platform + "/maps/map"; string streamingPath = Path.Combine("Assets/StreamingAssets/AssetBundles", Module.ModuleStateConfig.Json.CurrentTag[0]); byte[] buffer = new byte[20971520]; //20M缓存,不够会自动扩大 //以下为整体上Addon和Patch的不同 switch (Module.UserConfig.Json.PackageMode) { case "Patch": mapFilePathInPackage += "_" + Module.ModuleStateConfig.Json.ResourceVersion; break; case "Addon": Module.DisplayProgressBar("正在获取需要拷贝到Streaming中的Bundles信息", progress, true); progress += 0.01f; //得到需要拷贝到Streaming中的Bundles List <string> bundlesCopyToStreaming = new List <string>(); //List<string> bundlesCopyToStreaming_all = new List<string>(); foreach (var package in packages) { if (package.CopyToStreaming) { bundlesCopyToStreaming = bundlesCopyToStreaming.Union(package.Bundles).ToList(); } //bundlesCopyToStreaming_all = bundlesCopyToStreaming_all.Union(package.Bundles).ToList(); } //重建StreamingAssets/AssetBundles/[Platform]目录 Module.DisplayProgressBar("正在重建StreamingAssets目录:", "Assets/StreamingAssets/AssetBundles", progress, true); progress += 0.01f; if (Directory.Exists("Assets/StreamingAssets/AssetBundles")) { Directory.Delete("Assets/StreamingAssets/AssetBundles", true); } Directory.CreateDirectory(streamingPath); //构建PackageManifest.json Module.DisplayProgressBar("正在StreamingAssets中构建文件", "PackageManifest.json", progress, true); progress += 0.01f; List <PackageManifestStruct> packageManifest = new List <PackageManifestStruct>(); //单独加一个核心包的配置信息 string corePackageName = string.Join("_", new string[] { platform, Module.UserConfig.Json.PackageMode.ToLower(), Module.ModuleStateConfig.Json.ClientVersion, "Core" }) + Module.ModuleConfig.Json.PackageExtension; packageManifest.Add(new PackageManifestStruct { name_ = corePackageName, flag_ = G.NecesseryEnum.IndexOf("Immediate"), location_ = G.DeploymentLocationEnum.IndexOf("Built-in"), hasDownloaded_ = false }); //所有package的配置信息 foreach (var package in packages) { packageManifest.Add(new PackageManifestStruct { name_ = GetPackageFileName(package.PackageName, Module.ModuleStateConfig.Json.ResourceVersion), flag_ = G.NecesseryEnum.IndexOf(package.Necessery), location_ = G.DeploymentLocationEnum.IndexOf(package.DeploymentLocation), hasDownloaded_ = package.CopyToStreaming }); } string packageManifestContent = JsonConvert.SerializeObject(packageManifest, Formatting.Indented); File.WriteAllText(Path.Combine(streamingPath, "PackageManifest.json"), packageManifestContent); //构建核心包 string corePackagePath = Path.Combine(streamingPath, corePackageName); Module.DisplayProgressBar("正在向StreamingAssets中构建CorePackage", corePackagePath, progress, true); progress += 0.01f; using (FileStream zipFileStream = new FileStream(corePackagePath, FileMode.Create)) { using (ZipOutputStream zipStream = new ZipOutputStream(zipFileStream)) { zipStream.SetLevel(Module.UserConfig.Json.CompressionLevel); //构建bundle_version BuildBundleVersionInfoInZipStream(bundleVersionFilePathInPackage, Module.ModuleStateConfig.Json.ResourceVersion, bundlesCopyToStreaming, zipStream); //构建map BuildMapInZipStream(mapFilePathInPackage, buffer, zipStream); //添加Lua BuildLuaInZipStream(buffer, zipStream); } } //拷贝Assetbundle string bundlesRootPathInStreaming = Path.Combine(streamingPath, "AssetBundles"); int bundlesCopyToStreamingCount = bundlesCopyToStreaming.Count; for (int i = 0; i < bundlesCopyToStreamingCount; i++) { string bundle = bundlesCopyToStreaming[i]; Module.DisplayProgressBar(string.Format("正在向StreamingAssets中拷贝Bundles({0}/{1})", i + 1, bundlesCopyToStreamingCount), bundle, progress + (float)i / bundlesCopyToStreamingCount * 0.1f);//拷贝Assetbundle过程占整个过程的10% string targetPath = Path.Combine(bundlesRootPathInStreaming, bundle); Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); File.Copy(Path.Combine(bundlesFolderPath, bundle), targetPath, false); //这里不允许覆盖,若已存在则抛出异常 } progress += 0.1f; break; default: throw new EBPException("不能识别模式:" + Module.UserConfig.Json.PackageMode); } float restProgress = 1 - progress; for (int pi = 0; pi < packagesCount; pi++) { var package = packages[pi]; if (package.CopyToStreaming) //copyToStreaming的Package不打成Addon { continue; } using (FileStream zipFileStream = new FileStream(Path.Combine(packagesFolderPath, GetPackageFileName(package.PackageName, Module.ModuleStateConfig.Json.ResourceVersion)), FileMode.Create)) { using (ZipOutputStream zipStream = new ZipOutputStream(zipFileStream)) { zipStream.SetLevel(Module.UserConfig.Json.CompressionLevel); //构建Bundles int bundlesCount = package.Bundles.Count; for (int i = 0; i < bundlesCount; i++) { string bundleRelativePath = package.Bundles[i]; string bundlePath = Path.Combine(bundlesFolderPath, bundleRelativePath); Module.DisplayProgressBar(string.Format("正在打包{0}({1}/{2}) : ({3}/{4}) 总计:({5}/{6})", package.PackageName, pi + 1, packagesCount, i + 1, bundlesCount, count + 1, total), bundleRelativePath, progress + (float)count / total * restProgress); AddFileToZipStream(zipStream, bundlePath, Path.Combine(bundlesRootPathInPackage, bundleRelativePath), buffer); count++; } //构建空目录 int emptyFolderCount = package.EmptyFolders.Count; Module.DisplayProgressBar(string.Format("正在打包{0}({1}/{2}) : ({3}/{4}) 总计:({5}/{6})", package.PackageName, pi + 1, packagesCount, bundlesCount, bundlesCount, count, total), string.Format("Empty Folders (Total:{0})", emptyFolderCount), progress + (float)count / total * restProgress, true); for (int i = 0; i < emptyFolderCount; i++) { zipStream.PutNextEntry(new ZipEntry(package.EmptyFolders[i] + "/") { }); } //构建bundle_version BuildBundleVersionInfoInZipStream(bundleVersionFilePathInPackage, Module.ModuleStateConfig.Json.ResourceVersion, package.Bundles, zipStream); //以下为每个包中Patch和Addon独有内容 switch (Module.UserConfig.Json.PackageMode) { case "Patch": //构建map Module.DisplayProgressBar(string.Format("正在打包{0}({1}/{2}) : ({3}/{4}) 总计:({5}/{6})", package.PackageName, pi + 1, packagesCount, bundlesCount, bundlesCount, count, total), "Building Map...", progress + (float)count / total * restProgress, true); BuildMapInZipStream(mapFilePathInPackage, buffer, zipStream); //添加Lua Module.DisplayProgressBar(string.Format("正在打包{0}({1}/{2}) : ({3}/{4}) 总计:({5}/{6})", package.PackageName, pi + 1, packagesCount, bundlesCount, bundlesCount, count, total), "Adding Lua...", progress + (float)count / total * restProgress, true); BuildLuaInZipStream(buffer, zipStream); break; case "Addon": break; default: throw new EBPException("不能识别模式:" + Module.UserConfig.Json.PackageMode); } } } } }