123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511 |
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // Licensed under the MIT License. See LICENSE in the project root for license information.
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Threading;
- using UnityEditor;
- using UnityEditor.Build.Reporting;
- using UnityEngine;
- namespace XRTool.Util
- {
- public enum BuildTargets
- {
- NoHand = 0,
- Hand = 1,
- Both = 2,
- None = 3
- }
- /// <summary>
- /// 打包窗口
- /// </summary>
- public class BuildDeployWindow : EditorWindow
- {
- private Vector2 scrollPos;
- private static BuildConfig buildConf;
- /// <inheritdoc />
- public IEnumerable<string> Scenes { get; set; }
- public string outputPath;
- public bool isAutoUpdateVersion = true;
- private bool isOpenOutPath = true;
- private string realPath;
- private string serverPath;
- public BuildOptions buildOptions = BuildOptions.None;
- private string[] suffix = new string[] { ".exe", ".apk", "Project", };
- public string appName;
- private int buildIndex = 2;
- public const string initVersion = "1.0.0";
- private string allSymbol;
- private bool isAutoInstall = true;
- private string androidSDPath = "sdcard/Android/data/";
- private BuildTargets buildTargets;
-
- [MenuItem("XRTools/Build Window", false, 0)]
- public static void OpenWindow()
- {
- // Dock it next to the Scene View.
- var window = GetWindow<BuildDeployWindow>(typeof(SceneView));
- window.titleContent = new GUIContent("Build Window");
- window.Show();
- }
- private void OnEnable()
- {
- buildTargets = BuildTargets.None;
- PlayerSettings.companyName = "shadowcreator";
- buildIndex = 2;
- if (buildConf == null)
- {
- if (BuildConfigMgr.Instance.IsInit)
- {
- buildConf = BuildConfig.Instance;
- }
- else
- {
- UnityLog.LogError("配置初始化失败!");
- }
- //buildConf = AssetDatabase.LoadAssetAtPath<BuildConfig>("Assets/GameData/BuildConf/BuildConfig.asset");
- }
- titleContent = new GUIContent("Build Window");
- minSize = new Vector2(512, 256);
- CheckVersion();
- if (buildConf == null)
- {
- UnityLog.LogError("buildConf is null");
- }
- //UnityLog.Log(buildConf);
- }
- private void CheckVersion()
- {
- string version = PlayerSettings.bundleVersion;
- string[] curversion = version.Split('.');
- if (curversion.Length < 3)
- {
- PlayerSettings.bundleVersion = initVersion;
- Debug.Log("版本号初始化:" + initVersion);
- }
- }
- /// <summary>
- /// 更新版本号,在打包时调用此函数
- /// </summary>
- public string UpdateGameVersion()
- {
- string version = PlayerSettings.bundleVersion;
- string[] curversion = version.Split('.');
- if (curversion.Length < 3)
- {
- Debug.LogError("请规范版本号:" + initVersion);
- return PlayerSettings.bundleVersion;
- }
- ///测试版本,程序自测版本
- if (buildConf.buildType == BuildType.Test)
- {
- return PlayerSettings.bundleVersion;
- }
- int startIndex = (int)buildConf.buildVersion;
- int ver = int.Parse(curversion[startIndex]) + 1;
- curversion[startIndex] = ver.ToString();
- if (buildConf.buildVersion != BuildVersion.Build)
- {
- for (int i = startIndex + 1; i < curversion.Length; i++)
- {
- curversion[i] = "0";
- }
- }
- string newVersion = curversion[0];
- for (int i = 1; i < curversion.Length; i++)
- {
- newVersion += "." + curversion[i];
- }
- return newVersion;
- }
- private void ChangeHand()
- {
- if (buildTargets == BuildTargets.Hand)
- {
- PlayerSettings.productName = BuildConfig.Instance.appProName + "WithHand";
- BuildConfig.Instance.useHand = true;
- }
- else if (buildTargets == BuildTargets.NoHand)
- {
- PlayerSettings.productName = BuildConfig.Instance.appProName + "NoHand";
- BuildConfig.Instance.useHand = false;
- }
- else
- {
- PlayerSettings.productName = BuildConfig.Instance.appProName;
- BuildConfig.Instance.useHand = false;
- }
- if (buildTargets != BuildTargets.None)
- {
- PlayerSettings.applicationIdentifier = "com." + PlayerSettings.companyName + "." + PlayerSettings.productName;
- }
- BuildConfig.Instance.appPackName = PlayerSettings.applicationIdentifier;
- }
- /// <summary>
- /// 属性展示和同步
- /// </summary>
- private void OnGUI()
- {
- //buildConf = EditorGUI.ObjectField(new Rect(0, 5, 600, 20), "BuildSetting", buildConf, typeof(BuildConfig), true) as BuildConfig;
- if (!buildConf)
- {
- return;
- }
- scrollPos = GUI.BeginScrollView(new Rect(0, 30, position.width, position.height),
- scrollPos, new Rect(0, 0, 1920, 2160));
- BuildConfig.Instance.appProName = EditorGUILayout.TextField("应用名称", BuildConfig.Instance.appProName);
- BuildConfig.Instance.appPackName = EditorGUILayout.TextField("包名", BuildConfig.Instance.appPackName);
- buildConf.buildVersion = (BuildVersion)EditorGUILayout.EnumPopup("版本类型", buildConf.buildVersion);
- buildConf.buildType = (BuildType)EditorGUILayout.EnumPopup("发布模式", buildConf.buildType);
- buildConf.assetsType = (AssetsType)EditorGUILayout.EnumPopup("资源访问方式", buildConf.assetsType);
- buildConf.buildTarget = (BuildTarget)EditorGUILayout.EnumPopup("运行的平台", buildConf.buildTarget);
- buildConf.playType = (PlayType)EditorGUILayout.EnumPopup("运行的模式", buildConf.playType);
- //buildConf.buildTargetGroup = (BuildTargetGroup)EditorGUILayout.EnumPopup("发布的平台", buildConf.buildTargetGroup);
- buildConf.otherSymbol = EditorGUILayout.TextField("宏", buildConf.otherSymbol);
- allSymbol = EditorGUILayout.TextField("全部宏", allSymbol);
- if (string.IsNullOrEmpty(allSymbol))
- {
- allSymbol = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildConf.buildTargetGroup);
- }
- isAutoUpdateVersion = EditorGUILayout.Toggle("更新版本", isAutoUpdateVersion);
- isOpenOutPath = EditorGUILayout.Toggle("打开输出路径", isOpenOutPath);
- if (buildConf.buildTarget == BuildTarget.Android)
- {
- isAutoInstall = EditorGUILayout.Toggle("自动安装", isAutoInstall);
- }
- EditorGUILayout.LabelField("Version", PlayerSettings.bundleVersion);
- EditorGUILayout.LabelField("发布时间", buildConf.buildTime);
- outputPath = EditorGUILayout.TextField("输出路径", outputPath);
- if (string.IsNullOrEmpty(outputPath))
- {
- string path = Application.dataPath;
- path = path.Substring(0, path.LastIndexOf("/"));
- outputPath = path;
- }
- realPath = EditorGUILayout.TextField("完整路径", realPath);
- serverPath = EditorGUILayout.TextField("服务器地址", serverPath);
- androidSDPath = EditorGUILayout.TextField("安卓sd卡路径", androidSDPath);
- if (string.IsNullOrEmpty(realPath))
- {
- realPath = Path.Combine(outputPath, buildConf.buildTarget.ToString(), buildConf.playType.ToString(), Application.productName);
- }
- buildOptions = (BuildOptions)EditorGUILayout.EnumPopup("发布设置", buildOptions);
- var bd = buildTargets;
- buildTargets = (BuildTargets)EditorGUILayout.EnumPopup("发布操作方式", buildTargets);
- if (bd != buildTargets)
- {
- ChangeHand();
- }
- if (GUILayout.Button("重置版本号", GUILayout.Width(200)))
- {
- buildConf.appVersion = initVersion;
- PlayerSettings.bundleVersion = buildConf.appVersion;
- }
- if (GUILayout.Button("强制升级版本", GUILayout.Width(200)))
- {
- PlayerSettings.bundleVersion = UpdateGameVersion();
- }
- if (GUILayout.Button("同步设置", GUILayout.Width(200)))
- {
- SetDef();
- }
- if (GUILayout.Button("清空编辑器日志", GUILayout.Width(200)))
- {
- UnityLog.ClearAllLog();
- }
- if (GUILayout.Button("打开编辑器缓存路径", GUILayout.Width(200)))
- {
- OpenDirectory(Application.persistentDataPath);
- }
- if (buildConf.buildTarget == BuildTarget.Android && GUILayout.Button("安装", GUILayout.Width(200)))
- {
- if (!string.IsNullOrEmpty(appName) && !string.IsNullOrEmpty(realPath))
- {
- InstallApp(Path.Combine(realPath, appName));
- }
- }
- if (buildConf.buildTarget == BuildTarget.Android && GUILayout.Button("卸载", GUILayout.Width(200)))
- {
- if (!string.IsNullOrEmpty(appName) && !string.IsNullOrEmpty(realPath))
- {
- UnInstallApp();
- }
- }
- if (GUILayout.Button("清空Androd日志", GUILayout.Width(200)))
- {
- if (Directory.Exists(realPath + "/LogData"))
- {
- Directory.Delete(realPath + "/LogData", true);
- }
- }
- if (GUILayout.Button("拷贝缓存数据", GUILayout.Width(150)))
- {
- string resPath = "sdcard/ShadowCreate/MRStores/";
- string logPath = realPath + "/ShadowCreate/MRStores/";
- string[] files = new string[] { "DeviceDownInfo.xml" };
- if (!Directory.Exists(logPath))
- {
- Directory.CreateDirectory(logPath);
- }
- for (int i = 0; i < files.Length; i++)
- {
- string tmpPath = logPath + "/" + files[i];
- if (File.Exists(tmpPath))
- {
- File.Delete(tmpPath);
- }
- Thread newThread = new Thread(new ParameterizedThreadStart(RunCmd));
- string adb = "adb pull " + resPath + files[i] + " " + logPath;
- newThread.Start(adb);
- }
- OpenDirectory(logPath);
- }
- if (GUILayout.Button("拷贝日志到本地", GUILayout.Width(150)))
- {
- string resPath = androidSDPath + Application.identifier + "/files/LogData/";
- string logPath = realPath + "/LogData/" + buildConf.buildType.ToString() +
- "_" + PlayerSettings.bundleVersion + "/" + Application.version;
- string[] files = new string[] { "error.txt", "except.txt", "log.txt" };
- if (!Directory.Exists(logPath))
- {
- Directory.CreateDirectory(logPath);
- }
- for (int i = 0; i < files.Length; i++)
- {
- string tmpPath = logPath + "/" + files[i];
- if (File.Exists(tmpPath))
- {
- File.Delete(tmpPath);
- }
- Thread newThread = new Thread(new ParameterizedThreadStart(RunCmd));
- string adb = "adb pull " + resPath + files[i] + " " + logPath;
- newThread.Start(adb);
- }
- OpenDirectory(logPath);
- }
- if (GUILayout.Button("推送服务器地址", GUILayout.Width(150)))
- {
- string targetPath = androidSDPath + Application.identifier + "/files/";
- Thread newThread = new Thread(new ParameterizedThreadStart(RunCmd));
- string adb = "adb push " + serverPath + " " + targetPath;
- newThread.Start(adb);
- }
- if (GUILayout.Button("发布", GUILayout.Width(150)))
- {
- if (buildTargets != BuildTargets.Both)
- {
- DisPlayBuild(buildTargets);
- }
- else
- {
- ///先安装手势版本,再安装无手势版本
- DisPlayBuild(BuildTargets.Hand);
- isAutoUpdateVersion = false;
- DisPlayBuild(BuildTargets.NoHand);
- }
- }
- GUI.EndScrollView();
- //GUI.EndScrollView();
- if (GUI.changed)
- {
- UpdateSetting();
- }
- }
- public void DisPlayBuild(BuildTargets buildTargets)
- {
- string lastBuildTime = buildConf.buildTime;
- buildConf.buildTime = DateTime.Now.ToString();
- EditorUtility.SetDirty(buildConf);
- this.buildTargets = buildTargets;
- ChangeHand();
- ///设置宏编译指令
- SetDef();
- string lastVersion = PlayerSettings.bundleVersion;
- UpdateSetting();
- string newVersion = isAutoUpdateVersion ? UpdateGameVersion() : lastVersion;
- PlayerSettings.bundleVersion = newVersion;
- appName = Application.productName + "_" + buildConf.buildType.ToString() +
- "_" + PlayerSettings.bundleVersion + "_" + DateTime.Now.ToString("MMddHHmm") + suffix[buildIndex];
- bool isSucess = PlayerBuild(Path.Combine(realPath, appName));
- if (!isSucess)
- {
- PlayerSettings.bundleVersion = lastVersion;
- buildConf.buildTime = lastBuildTime;
- EditorUtility.SetDirty(buildConf);
- }
- else
- {
- if (isOpenOutPath)
- {
- OpenDirectory(realPath);
- }
- if (buildConf.buildTarget == BuildTarget.Android && isAutoInstall)
- {
- InstallApp(Path.Combine(realPath, appName));
- }
- }
- Debug.Log("当前版本" + PlayerSettings.bundleVersion);
- }
- private void InstallApp(string realPath)
- {
- if (File.Exists(realPath))
- {
- Thread newThread = new Thread(new ParameterizedThreadStart(RunCmd));
- string cmd = "adb install -r -d " + realPath;
- newThread.Start(cmd);
- }
- else
- {
- UnityLog.LogError(realPath + " 不存在");
- }
- }
- private void UnInstallApp()
- {
- Thread newThread = new Thread(new ParameterizedThreadStart(RunCmd));
- string cmd = "adb uninstall " + Application.identifier;
- newThread.Start(cmd);
- }
- private void UpdateSetting()
- {
- if (buildConf.buildTarget == BuildTarget.Android)
- {
- buildConf.buildTargetGroup = BuildTargetGroup.Android;
- if (EditorUserBuildSettings.exportAsGoogleAndroidProject)
- {
- buildIndex = 2;
- }
- else
- {
- buildIndex = 1;
- }
- }
- if (buildConf.buildTarget == BuildTarget.iOS)
- {
- buildConf.buildTargetGroup = BuildTargetGroup.iOS;
- buildIndex = 2;
- }
- if (buildConf.buildTarget == BuildTarget.StandaloneWindows)
- {
- buildConf.buildTargetGroup = BuildTargetGroup.Standalone;
- buildIndex = 0;
- }
- //buildConf.buildType.ToString(), buildConf.playType.ToString(),
- realPath = Path.Combine(outputPath, Application.productName, buildConf.buildTarget.ToString(), buildConf.playType.ToString());
- }
- private bool PlayerBuild(string path)
- {
- if (EditorUserBuildSettings.activeBuildTarget != buildConf.buildTarget)
- {
- EditorUserBuildSettings.SwitchActiveBuildTarget(buildConf.buildTargetGroup, buildConf.buildTarget);
- }
- BuildReport buildReport = Build(path);
- bool success = buildReport != null && buildReport.summary.result == BuildResult.Succeeded;
- return success;
- }
- private BuildReport Build(string path)
- {
- Scenes = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(scene => scene.path);
- EditorUtility.DisplayProgressBar("Build Pipeline", "Gathering Build Data...", 0.25f);
- BuildReport buildReport = default;
- try
- {
- buildReport = BuildPipeline.BuildPlayer(
- Scenes.ToArray(),
- path,
- EditorUserBuildSettings.activeBuildTarget, buildOptions);
- }
- catch (Exception e)
- {
- Debug.LogError($"{e.Message}\n{e.StackTrace}");
- }
- EditorUtility.ClearProgressBar();
- return buildReport;
- }
- private void SetDef()
- {
- string lastSym = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildConf.buildTargetGroup);
- Debug.Log(lastSym);
- ///设置指令用;分割
- string symbol = string.Format("buildType_{0};assetsType_{1};buildPlatform_{2};playType_{3}",
- buildConf.buildType, buildConf.assetsType, buildConf.buildTarget, buildConf.playType).ToUpper() + ";" + buildConf.otherSymbol;
- if (symbol != lastSym)
- {
- Debug.Log(lastSym + "当前宏编译配置:" + symbol);
- PlayerSettings.SetScriptingDefineSymbolsForGroup(buildConf.buildTargetGroup, symbol);
- }
- allSymbol = symbol;
- }
- /// <summary>
- /// 弹出指定的文件窗口,仅windows和mac使用
- /// </summary>
- /// <param name="path"></param>
- public static void OpenDirectory(string path)
- {
- if (string.IsNullOrEmpty(path)) return;
- if (!Directory.Exists(path))
- {
- UnityEngine.Debug.LogError("No Directory: " + path);
- return;
- }
- //Application.dataPath 只能在主线程中获取
- int lastIndex = Application.dataPath.LastIndexOf("/");
- string shellPath = Application.dataPath.Substring(0, lastIndex) + "/Shell/";
- // 新开线程防止锁死
- Thread newThread = new Thread(new ParameterizedThreadStart(CmdOpenDirectory));
- newThread.Start(path);
- }
- private static void CmdOpenDirectory(object obj)
- {
- System.Diagnostics.Process p = new System.Diagnostics.Process();
- #if UNITY_EDITOR_WIN
- p.StartInfo.FileName = "cmd.exe";
- p.StartInfo.Arguments = "/c start " + obj.ToString();
- #elif UNITY_EDITOR_OSX
- p.StartInfo.FileName = "bash";
- string shPath = shellPath + "openDir.sh";
- p.StartInfo.Arguments = shPath + " " + obj.ToString();
- #endif
- //UnityEngine.Debug.Log(p.StartInfo.Arguments);
- p.StartInfo.UseShellExecute = false;
- p.StartInfo.RedirectStandardInput = true;
- p.StartInfo.RedirectStandardOutput = true;
- p.StartInfo.RedirectStandardError = true;
- p.StartInfo.CreateNoWindow = true;
- p.Start();
- p.WaitForExit();
- p.Close();
- }
- private static void RunCmd(object command)
- {
- //例Process
- System.Diagnostics.Process p = new System.Diagnostics.Process();
- p.StartInfo.FileName = "cmd.exe"; //确定程序名
- p.StartInfo.Arguments = "/c " + command.ToString(); //确定程式命令行
- p.StartInfo.UseShellExecute = false; //Shell的使用
- p.StartInfo.RedirectStandardInput = true; //重定向输入
- p.StartInfo.RedirectStandardOutput = true; //重定向输出
- p.StartInfo.RedirectStandardError = true; //重定向输出错误
- p.StartInfo.CreateNoWindow = false; //设置置不显示示窗口
- p.Start();
- //return p.StandardOutput.ReadToEnd(); //输出出流取得命令行结果果
- }
- }
- }
|