using UnityEngine; using UnityEditor; using System.IO; using System; using GameEditor.FrameTool; public class AutoPack : EditorWindow { static string[][] PackConfig = new string[][] { new string[]{"喜扑", "Logo_cn_xipu", "MHT_CN_XIPU"}, new string[]{"草花", "Logo_cn_xipu", "MHT_CN_MIDDLE_WARE" }, }; #if UNITY_ANDROID static string Platform = "Android"; static string ConfigFileName = "config.txt"; static string VersionFileName = "version.txt"; #elif UNITY_IOS static string Platform = "IOS"; static string ConfigFileName = "config.txt"; static string VersionFileName = "game.info"; #else static string Platform = "Android"; static string ConfigFileName = "config.txt"; static string VersionFileName = "version.txt"; #endif static string MomPackPath; static string ExportPackPath; static string ScenePath; static string ABPath; // 判断是否要重新导出工程 static string[] ExportTypeList = { "导出工程,替换出包", "只替换AB出包", "只出包" }; static int ExportType; static bool[] Chooser; static bool isObb = false; private void OnEnable() { MomPackPath = EditorPrefs.GetString("MomPackPath", ""); ExportPackPath = Application.dataPath.Replace("Assets", "ExportProject"); ScenePath = Application.dataPath + "/LuaFramework/Scenes/"; ABPath = Application.dataPath + "/../BuildABs/" + Platform + "/"; ExportType = 2; Chooser = new bool[PackConfig.Length]; } /// /// 版本文件路径 /// static string _MomPackPath { get { return MomPackPath + "/" + Platform + "/"; } } //bool isBuild = false; //static bool isZs = false; //static string[] versionArr = new string[15]; //static int verIndex = 0; //static string curProjectDir; //static string m_ExcelPath; //static string[] excelArr; //static int excelIndex=0; //打包数据 [MenuItem("自动化打包/一键导出")] private static void EzBuildPack() { //创建窗口 Rect wr = new Rect(0, 0, 500, 700); var buildWin = GetWindowWithRect(wr, true); buildWin.titleContent = new GUIContent("打包工具"); buildWin.Show(); } private void OnGUI() { EditorGUILayout.BeginVertical(); EditorGUILayout.Space(); EditorGUILayout.Space(); //EditorGUILayout.LabelField(""); MomPackPath = EditorGUILayout.TextField("母包工程地址:", MomPackPath); if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false))) { MomPackPath = EditorUtility.OpenFolderPanel("Resource path", MomPackPath, MomPackPath); EditorPrefs.SetString("MomPackPath", MomPackPath); } EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.LabelField("请选择要打的包:"); for(int i = 0; i < PackConfig.Length; i++) { EditorGUILayout.BeginVertical(); Chooser[i] = EditorGUILayout.ToggleLeft(PackConfig[i][0], Chooser[i]); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("编辑Config", GUILayout.Height(20f))) { string tpath = _MomPackPath + PackConfig[i][2] + "/Config/" + ConfigFileName; GameEditor.Util.ProcessUtil.OpenText(tpath); } if (GUILayout.Button("编辑Version", GUILayout.Height(20f))) { string tpath = _MomPackPath + PackConfig[i][2] + "/Config/" + VersionFileName; GameEditor.Util.ProcessUtil.OpenText(tpath); } if (GUILayout.Button("编辑Gradle", GUILayout.Height(20f))) { string tpath = _MomPackPath + PackConfig[i][2] + "/build.gradle"; GameEditor.Util.ProcessUtil.OpenText(tpath); } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUILayout.Space(); EditorGUILayout.Space(); } ExportType = EditorGUILayout.Popup("请选择出包方式", ExportType, ExportTypeList); EditorGUILayout.Space(); EditorGUILayout.Space(); if (GUILayout.Button("开始", GUILayout.Height(40f))) { StartExport(); } } public static void StartExport() { if (MomPackPath.Equals("")) { EditorUtility.DisplayDialog("提示", "母包工程地址错误", "确定"); return; } bool check_result = false; for (int i = 0; i < Chooser.Length; i++) { if (!Chooser[i]) continue; string sceneFilePath = ScenePath + PackConfig[i][1]; if (!File.Exists(sceneFilePath + ".unity")) { Debug.LogError(PackConfig[i][0] + " 未找到场景:" + sceneFilePath); check_result = true; } string momPath = _MomPackPath + PackConfig[i][2]; if (!Directory.Exists(momPath)) { Debug.LogError(PackConfig[i][0] + " 未找到母包:" + momPath); check_result = true; } } if (check_result) { EditorUtility.DisplayDialog("提示", "包路径错误", "确定"); return; } // 开始导出 for (int i = 0; i < Chooser.Length; i++) { if (!Chooser[i]) continue; switch (ExportType) { case 0: // 导出工程 ExportAS(i); ReplaceFromProject(i); ReplaceConfigAndVersion(i); StartGradleBuild(i); break; case 1: // 只替换AB ReplaceFromAB(i); ReplaceConfigAndVersion(i); StartGradleBuild(i); break; case 2: // 只重新打包 ReplaceConfigAndVersion(i); StartGradleBuild(i); break; } } } // 导出android 工程 public static void ExportAS(int index) { string pName = PackConfig[index][1] + "__" + PackConfig[index][2]; PlayerSettings.productName = pName; PlayerSettings.Android.useAPKExpansionFiles = isObb; if (isObb) { pName += "__obb"; } if (!Directory.Exists(ExportPackPath)) { Directory.CreateDirectory(ExportPackPath); } if (Directory.Exists(ExportPackPath + "/" + pName)) { Directory.Delete(ExportPackPath + "/" + pName, true); } EditorUserBuildSettings.exportAsGoogleAndroidProject = true; EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle; // 设置需要打包的场景 string launchScene = "Assets/LuaFramework/Scenes/" + PackConfig[index][1] + ".unity"; Debug.Log(PackConfig[index][0] + ":打包场景:" + launchScene); BuildPlayerOptions bpo = new BuildPlayerOptions(); bpo.locationPathName = ExportPackPath; bpo.options = BuildOptions.None; //bpo.options |= BuildOptions.AcceptExternalModificationsToPlayer; bpo.scenes = new[] { launchScene }; bpo.target = BuildTarget.Android; // 调用开始打包 BuildPipeline.BuildPlayer(bpo); Debug.Log(PackConfig[index][0] + ":android工程导出路径" + ExportPackPath + "/" + pName); Debug.Log(PackConfig[index][0] + ":android工程导出完成"); } static string[] ReplaceDir = new string[] { "/src/main/assets/Android", "/src/main/assets/bin", "/src/main/jniLibs" }; // 从工程中替换 private static void ReplaceFromProject(int index) { string fromPath = ExportPackPath + "/" + PackConfig[index][1] + "__" + PackConfig[index][2]; string toPath = _MomPackPath + PackConfig[index][2]; for (int i = 0; i < ReplaceDir.Length; i++) { string dir = ReplaceDir[i]; string to = toPath + dir; if (Directory.Exists(to)) Directory.Delete(to, true); Directory.CreateDirectory(to); GameCore.FileUtils.CopyDir(fromPath + dir, to); } Debug.Log(PackConfig[index][0] + ":母包工程资源替换完成"); // 替换build-id EditorUtility.DisplayProgressBar("重写AndroidManifest", "", 1f); RewriteManifest(fromPath + "/src/main/AndroidManifest.xml", toPath + "/src/main/AndroidManifest.xml"); Debug.Log(PackConfig[index][0] + ":母包Manifest修改完成"); EditorUtility.ClearProgressBar(); } private static void RewriteManifest(string f, string t) { // 找到要替换的内容 string[] flines = File.ReadAllLines(f, System.Text.Encoding.UTF8); string rpl = ""; for (int fi = 0; fi < flines.Length; fi++) { if (flines[fi].Contains("unity.build-id")) { rpl = flines[fi]; break; } } // 判断是否正确 if (rpl.Equals("")) { return; } // 替换到母包中 string[] tlines = File.ReadAllLines(t, System.Text.Encoding.UTF8); string[] wlines = new string[tlines.Length - 1]; string lastLine = ""; for (int ti = 0; ti < tlines.Length; ti++) { if (tlines[ti].Contains("unity.build-id")) { tlines[ti] = rpl; } if (ti == tlines.Length - 1) { lastLine = tlines[ti]; } else { wlines[ti] = tlines[ti]; } } File.WriteAllLines(t, wlines, System.Text.Encoding.UTF8); File.AppendAllText(t, lastLine, System.Text.Encoding.UTF8); } // 从AB包替换 private static void ReplaceFromAB(int index) { string toPath = _MomPackPath + PackConfig[index][2] + "/src/main/assets/Android"; if (Directory.Exists(toPath)) Directory.Delete(toPath, true); Directory.CreateDirectory(toPath); GameCore.FileUtils.CopyDir(ABPath, toPath); Debug.Log(PackConfig[index][0] + ":替换AB包完成"); } // 替换配置文件 private static void ReplaceConfigAndVersion(int index) { EditorUtility.DisplayProgressBar("替换配置文件", "", 1f); string toPath = _MomPackPath + PackConfig[index][2] + "/src/main/assets/Android/"; string fromPath = _MomPackPath + PackConfig[index][2] + "/Config/"; File.Copy(fromPath + ConfigFileName, toPath + ConfigFileName, true); File.Copy(fromPath + VersionFileName, toPath + VersionFileName, true); Debug.Log(PackConfig[index][0]+":配置文件替换完成"); EditorUtility.ClearProgressBar(); } // 开始生成apk private static void StartGradleBuild(int index) { EditorUtility.DisplayProgressBar("正在生成APK", "", 1f); string apkPath = _MomPackPath + PackConfig[index][2] + "/APK/"; if (!Directory.Exists(apkPath)) { Directory.CreateDirectory(apkPath); } string time = DateTime.Now.ToString("yyyy_MM_dd_hh_mm_ss"); if (!Directory.Exists(apkPath + time)) { Directory.CreateDirectory(apkPath + time); } GameEditor.Util.ProcessUtil.ProcessCommand(_MomPackPath + PackConfig[index][2], "gradlew assembleRelease>" + apkPath + time +"/_log.txt"); EditorUtility.DisplayProgressBar("正在导出APK", "", 1f); string apkFilePath = _MomPackPath + PackConfig[index][2] + "/build/outputs/apk/release/" + PackConfig[index][2] + "-release.apk"; if (File.Exists(apkFilePath)) { File.Copy(apkFilePath, apkPath + time + "/" + PackConfig[index][2] + ".apk"); } Debug.Log(PackConfig[index][0] + ":打包完成"); EditorUtility.ClearProgressBar(); } //private static void ExportXcode(string _sceneName) //{ // PlayerSettings.productName = "太初行"; // string mainXcodePath = // isZs? "/Volumes/ELEMENTS/JieLing/Packager/IOS/MHT_HW_RELEASE": "/Volumes/ELEMENTS/JieLing/Packager/IOS/MHT_HW_TEST"; // string outPath = isZs?"/Volumes/ELEMENTS/JieLing/Packager/IOS/exXcodePro_Release":"/Volumes/ELEMENTS/JieLing/Packager/IOS/exXcodePro_Test"; // if (Directory.Exists(outPath)) // { // Directory.Delete(outPath, true); // } // // 设置需要打包的场景 // string launchScene = _sceneName; // Debug.Log("打包场景:" + launchScene); // BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); // buildPlayerOptions.locationPathName = outPath; // buildPlayerOptions.options = BuildOptions.None; // buildPlayerOptions.options |= BuildOptions.AcceptExternalModificationsToPlayer; // buildPlayerOptions.scenes = new[] { launchScene }; // buildPlayerOptions.target = BuildTarget.iOS; // // 调用开始打包 // BuildPipeline.BuildPlayer(buildPlayerOptions); // Debug.Log("打包完成"); // Debug.Log("导出工程路径:"+ outPath); // if (Directory.Exists(mainXcodePath)&& Directory.Exists(outPath)) // { // Debug.Log("替换xcode资源"); // Directory.Delete(mainXcodePath+"/Data", true); // Directory.Move(outPath+"/Data",mainXcodePath+"/Data"); // Directory.Delete(mainXcodePath+"/Classes/Native", true); // Directory.Move(outPath+"/Classes/Native",mainXcodePath+"/Classes/Native"); // } //} }