BuildProfileInspector.cs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text;
  5. using UnityEditor;
  6. using UnityEngine;
  7. [CustomEditor(typeof(BuildProfile))]
  8. public sealed class BuildProfileInspector : Editor
  9. {
  10. private readonly Dictionary<BuildTask, bool> foldoutMap = new Dictionary<BuildTask, bool>();
  11. private Vector2 scroll = Vector2.zero;
  12. private BuildProfile profile;
  13. private void OnEnable()
  14. {
  15. profile = target as BuildProfile;
  16. }
  17. public override void OnInspectorGUI()
  18. {
  19. GUILayout.BeginHorizontal();
  20. {
  21. if (GUILayout.Button("新建", "ButtonLeft"))
  22. {
  23. Undo.RecordObject(profile, "Create");
  24. var task = new BuildTask()
  25. {
  26. ProductName = "Product Name",
  27. BuildTarget = BuildTarget.StandaloneWindows64,
  28. BuildPath = Directory.GetParent(Application.dataPath).FullName
  29. };
  30. profile.BuildTasks.Add(task);
  31. }
  32. if (GUILayout.Button("展开", "ButtonMid"))
  33. {
  34. for (int i = 0; i < profile.BuildTasks.Count; i++)
  35. {
  36. foldoutMap[profile.BuildTasks[i]] = true;
  37. }
  38. }
  39. if (GUILayout.Button("收缩", "ButtonMid"))
  40. {
  41. for (int i = 0; i < profile.BuildTasks.Count; i++)
  42. {
  43. foldoutMap[profile.BuildTasks[i]] = false;
  44. }
  45. }
  46. GUI.color = Color.yellow;
  47. if (GUILayout.Button("清空", "ButtonMid"))
  48. {
  49. Undo.RecordObject(profile, "Clear");
  50. if (EditorUtility.DisplayDialog("提醒", "是否确定清空列表?", "确定", "取消"))
  51. {
  52. profile.BuildTasks.Clear();
  53. }
  54. }
  55. GUI.color = Color.cyan;
  56. if (GUILayout.Button("打包", "ButtonRight"))
  57. {
  58. if (EditorUtility.DisplayDialog("提醒", "打包需要耗费一定时间,是否确定开始?", "确定", "取消"))
  59. {
  60. StringBuilder sb = new StringBuilder();
  61. sb.Append("打包报告:\r\n");
  62. for (int i = 0; i < profile.BuildTasks.Count; i++)
  63. {
  64. EditorUtility.DisplayProgressBar("Build", "Building...", i + 1 / profile.BuildTasks.Count);
  65. var task = profile.BuildTasks[i];
  66. task.BuildPath = Path.Combine(profile.BuildPath, task.ProductName);
  67. if(!Directory.Exists(task.BuildPath))
  68. {
  69. Directory.CreateDirectory(task.BuildPath);
  70. }
  71. List<EditorBuildSettingsScene> buildScenes = new List<EditorBuildSettingsScene>();
  72. for (int j = 0; j < task.SceneAssets.Count; j++)
  73. {
  74. var scenePath = AssetDatabase.GetAssetPath(task.SceneAssets[j]);
  75. if (!string.IsNullOrEmpty(scenePath))
  76. {
  77. buildScenes.Add(new EditorBuildSettingsScene(scenePath, true));
  78. }
  79. }
  80. string locationPathName = $"{task.BuildPath}/{task.ProductName + ".exe"}";
  81. var report = BuildPipeline.BuildPlayer(buildScenes.ToArray(), locationPathName, task.BuildTarget, BuildOptions.None);
  82. sb.Append($"[{task.ProductName + ".exe"}] 打包结果: {report.summary.result}\r\n");
  83. }
  84. EditorUtility.ClearProgressBar();
  85. Debug.Log(sb.ToString());
  86. }
  87. return;
  88. }
  89. GUI.color = Color.white;
  90. }
  91. GUILayout.EndHorizontal();
  92. GUILayout.BeginHorizontal();
  93. GUILayout.Label("打包路径根节点:", GUILayout.Width(100));
  94. GUILayout.TextField(profile.BuildPath);
  95. if (GUILayout.Button("Browse", GUILayout.Width(60)))
  96. {
  97. profile.BuildPath = EditorUtility.SaveFolderPanel("Build Path Root", profile.BuildPath, "");
  98. }
  99. GUILayout.EndHorizontal();
  100. scroll = GUILayout.BeginScrollView(scroll);
  101. {
  102. for (int i = 0; i < profile.BuildTasks.Count; i++)
  103. {
  104. var task = profile.BuildTasks[i];
  105. if (!foldoutMap.ContainsKey(task)) foldoutMap.Add(task, true);
  106. GUILayout.BeginHorizontal("Badge");
  107. GUILayout.Space(12);
  108. foldoutMap[task] = EditorGUILayout.Foldout(foldoutMap[task], $"{task.ProductName}", true);
  109. GUILayout.Label(string.Empty);
  110. if (GUILayout.Button(EditorGUIUtility.IconContent("TreeEditor.Trash"), "IconButton", GUILayout.Width(20)))
  111. {
  112. Undo.RecordObject(profile, "Delete Task");
  113. foldoutMap.Remove(task);
  114. profile.BuildTasks.Remove(task);
  115. break;
  116. }
  117. GUILayout.EndHorizontal();
  118. if (foldoutMap[task])
  119. {
  120. GUILayout.BeginVertical("Box");
  121. GUILayout.BeginHorizontal();
  122. GUILayout.Label("打包场景:", GUILayout.Width(70));
  123. if (GUILayout.Button(EditorGUIUtility.IconContent("Toolbar Plus More"), GUILayout.Width(28)))
  124. {
  125. task.SceneAssets.Add(null);
  126. }
  127. GUILayout.EndHorizontal();
  128. if (task.SceneAssets.Count > 0)
  129. {
  130. GUILayout.BeginHorizontal();
  131. GUILayout.Space(75);
  132. GUILayout.BeginVertical("Badge");
  133. for (int j = 0; j < task.SceneAssets.Count; j++)
  134. {
  135. var sceneAsset = task.SceneAssets[j];
  136. GUILayout.BeginHorizontal();
  137. GUILayout.Label($"{j + 1}.", GUILayout.Width(20));
  138. task.SceneAssets[j] = EditorGUILayout.ObjectField(sceneAsset, typeof(SceneAsset), false) as SceneAsset;
  139. if (GUILayout.Button("↑", "MiniButtonLeft", GUILayout.Width(20)))
  140. {
  141. if (j > 0)
  142. {
  143. Undo.RecordObject(profile, "Move Up Scene Assets");
  144. var temp = task.SceneAssets[j - 1];
  145. task.SceneAssets[j - 1] = sceneAsset;
  146. task.SceneAssets[j] = temp;
  147. }
  148. }
  149. if (GUILayout.Button("↓", "MiniButtonMid", GUILayout.Width(20)))
  150. {
  151. if (j < task.SceneAssets.Count - 1)
  152. {
  153. Undo.RecordObject(profile, "Move Down Scene Assets");
  154. var temp = task.SceneAssets[j + 1];
  155. task.SceneAssets[j + 1] = sceneAsset;
  156. task.SceneAssets[j] = temp;
  157. }
  158. }
  159. if (GUILayout.Button(EditorGUIUtility.IconContent("Toolbar Plus"), "MiniButtonMid", GUILayout.Width(20)))
  160. {
  161. Undo.RecordObject(profile, "Add Scene Assets");
  162. task.SceneAssets.Insert(j + 1, null);
  163. break;
  164. }
  165. if (GUILayout.Button(EditorGUIUtility.IconContent("Toolbar Minus"), "MiniButtonMid", GUILayout.Width(20)))
  166. {
  167. Undo.RecordObject(profile, "Delete Scene Assets");
  168. task.SceneAssets.RemoveAt(j);
  169. break;
  170. }
  171. GUILayout.EndHorizontal();
  172. }
  173. GUILayout.EndVertical();
  174. GUILayout.EndHorizontal();
  175. }
  176. GUILayout.BeginHorizontal();
  177. GUILayout.Label("产品名称:", GUILayout.Width(70));
  178. var newPN = GUILayout.TextField(task.ProductName);
  179. if (task.ProductName != newPN)
  180. {
  181. Undo.RecordObject(profile, "Product Name");
  182. task.ProductName = newPN;
  183. }
  184. GUILayout.EndHorizontal();
  185. GUILayout.BeginHorizontal();
  186. GUILayout.Label("打包平台:", GUILayout.Width(70));
  187. var newBT = (BuildTarget)EditorGUILayout.EnumPopup(task.BuildTarget);
  188. if (task.BuildTarget != newBT)
  189. {
  190. Undo.RecordObject(profile, "Build Target");
  191. task.BuildTarget = newBT;
  192. }
  193. GUILayout.EndHorizontal();
  194. //GUILayout.BeginHorizontal();
  195. //GUILayout.Label("打包路径:", GUILayout.Width(70));
  196. //GUILayout.TextField(task.BuildPath);
  197. //if (GUILayout.Button("Browse", GUILayout.Width(60)))
  198. //{
  199. // task.BuildPath = EditorUtility.SaveFolderPanel("Build Path", task.BuildPath, "");
  200. //}
  201. //GUILayout.EndHorizontal();
  202. GUILayout.EndVertical();
  203. }
  204. }
  205. }
  206. GUILayout.EndScrollView();
  207. serializedObject.ApplyModifiedProperties();
  208. if (GUI.changed) EditorUtility.SetDirty(profile);
  209. }
  210. }