ResourceBuilder.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. //------------------------------------------------------------
  2. // Game Framework
  3. // Copyright © 2013-2021 loyalsoft. All rights reserved.
  4. // Homepage: http://www.game7000.com/
  5. // Feedback: http://www.game7000.com/
  6. //------------------------------------------------------------
  7. using GameFramework;
  8. using System;
  9. using System.IO;
  10. using UnityEditor;
  11. using UnityEngine;
  12. namespace UnityGameFramework.Editor.ResourceTools
  13. {
  14. /// <summary>
  15. /// 资源生成器。
  16. /// </summary>
  17. internal sealed class ResourceBuilder : EditorWindow
  18. {
  19. private ResourceBuilderController m_Controller = null;
  20. private bool m_OrderBuildResources = false;
  21. private int m_CompressionHelperTypeNameIndex = 0;
  22. private int m_BuildEventHandlerTypeNameIndex = 0;
  23. [MenuItem("Game Framework/Resource Tools/Resource Builder", false, 40)]
  24. private static void Open()
  25. {
  26. ResourceBuilder window = GetWindow<ResourceBuilder>("Resource Builder", true);
  27. #if UNITY_2019_3_OR_NEWER
  28. window.minSize = new Vector2(800f, 640f);
  29. #else
  30. window.minSize = new Vector2(800f, 600f);
  31. #endif
  32. }
  33. private void OnEnable()
  34. {
  35. m_Controller = new ResourceBuilderController();
  36. m_Controller.OnLoadingResource += OnLoadingResource;
  37. m_Controller.OnLoadingAsset += OnLoadingAsset;
  38. m_Controller.OnLoadCompleted += OnLoadCompleted;
  39. m_Controller.OnAnalyzingAsset += OnAnalyzingAsset;
  40. m_Controller.OnAnalyzeCompleted += OnAnalyzeCompleted;
  41. m_Controller.ProcessingAssetBundle += OnProcessingAssetBundle;
  42. m_Controller.ProcessingBinary += OnProcessingBinary;
  43. m_Controller.ProcessResourceComplete += OnProcessResourceComplete;
  44. m_Controller.BuildResourceError += OnBuildResourceError;
  45. m_OrderBuildResources = false;
  46. if (m_Controller.Load())
  47. {
  48. Debug.Log("Load configuration success.");
  49. m_CompressionHelperTypeNameIndex = 0;
  50. string[] compressionHelperTypeNames = m_Controller.GetCompressionHelperTypeNames();
  51. for (int i = 0; i < compressionHelperTypeNames.Length; i++)
  52. {
  53. if (m_Controller.CompressionHelperTypeName == compressionHelperTypeNames[i])
  54. {
  55. m_CompressionHelperTypeNameIndex = i;
  56. break;
  57. }
  58. }
  59. m_Controller.RefreshCompressionHelper();
  60. m_BuildEventHandlerTypeNameIndex = 0;
  61. string[] buildEventHandlerTypeNames = m_Controller.GetBuildEventHandlerTypeNames();
  62. for (int i = 0; i < buildEventHandlerTypeNames.Length; i++)
  63. {
  64. if (m_Controller.BuildEventHandlerTypeName == buildEventHandlerTypeNames[i])
  65. {
  66. m_BuildEventHandlerTypeNameIndex = i;
  67. break;
  68. }
  69. }
  70. m_Controller.RefreshBuildEventHandler();
  71. }
  72. else
  73. {
  74. Debug.LogWarning("Load configuration failure.");
  75. }
  76. }
  77. private void Update()
  78. {
  79. if (m_OrderBuildResources)
  80. {
  81. m_OrderBuildResources = false;
  82. BuildResources();
  83. }
  84. }
  85. private void OnGUI()
  86. {
  87. EditorGUILayout.BeginVertical(GUILayout.Width(position.width), GUILayout.Height(position.height));
  88. {
  89. GUILayout.Space(5f);
  90. EditorGUILayout.LabelField("Environment Information", EditorStyles.boldLabel);
  91. EditorGUILayout.BeginVertical("box");
  92. {
  93. EditorGUILayout.BeginHorizontal();
  94. {
  95. EditorGUILayout.LabelField("Product Name", GUILayout.Width(160f));
  96. EditorGUILayout.LabelField(m_Controller.ProductName);
  97. }
  98. EditorGUILayout.EndHorizontal();
  99. EditorGUILayout.BeginHorizontal();
  100. {
  101. EditorGUILayout.LabelField("Company Name", GUILayout.Width(160f));
  102. EditorGUILayout.LabelField(m_Controller.CompanyName);
  103. }
  104. EditorGUILayout.EndHorizontal();
  105. EditorGUILayout.BeginHorizontal();
  106. {
  107. EditorGUILayout.LabelField("Game Identifier", GUILayout.Width(160f));
  108. EditorGUILayout.LabelField(m_Controller.GameIdentifier);
  109. }
  110. EditorGUILayout.EndHorizontal();
  111. EditorGUILayout.BeginHorizontal();
  112. {
  113. EditorGUILayout.LabelField("Game Framework Version", GUILayout.Width(160f));
  114. EditorGUILayout.LabelField(m_Controller.GameFrameworkVersion);
  115. }
  116. EditorGUILayout.EndHorizontal();
  117. EditorGUILayout.BeginHorizontal();
  118. {
  119. EditorGUILayout.LabelField("Unity Version", GUILayout.Width(160f));
  120. EditorGUILayout.LabelField(m_Controller.UnityVersion);
  121. }
  122. EditorGUILayout.EndHorizontal();
  123. EditorGUILayout.BeginHorizontal();
  124. {
  125. EditorGUILayout.LabelField("Applicable Game Version", GUILayout.Width(160f));
  126. EditorGUILayout.LabelField(m_Controller.ApplicableGameVersion);
  127. }
  128. EditorGUILayout.EndHorizontal();
  129. }
  130. EditorGUILayout.EndVertical();
  131. GUILayout.Space(5f);
  132. EditorGUILayout.BeginHorizontal();
  133. {
  134. EditorGUILayout.BeginVertical();
  135. {
  136. EditorGUILayout.LabelField("Platforms", EditorStyles.boldLabel);
  137. EditorGUILayout.BeginHorizontal("box");
  138. {
  139. EditorGUILayout.BeginVertical();
  140. {
  141. DrawPlatform(Platform.Windows, "Windows");
  142. DrawPlatform(Platform.Windows64, "Windows x64");
  143. DrawPlatform(Platform.MacOS, "macOS");
  144. }
  145. EditorGUILayout.EndVertical();
  146. EditorGUILayout.BeginVertical();
  147. {
  148. DrawPlatform(Platform.Linux, "Linux");
  149. DrawPlatform(Platform.IOS, "iOS");
  150. DrawPlatform(Platform.Android, "Android");
  151. }
  152. EditorGUILayout.EndVertical();
  153. EditorGUILayout.BeginVertical();
  154. {
  155. DrawPlatform(Platform.WindowsStore, "Windows Store");
  156. DrawPlatform(Platform.WebGL, "WebGL");
  157. }
  158. EditorGUILayout.EndVertical();
  159. }
  160. EditorGUILayout.EndHorizontal();
  161. }
  162. EditorGUILayout.EndVertical();
  163. }
  164. EditorGUILayout.EndHorizontal();
  165. GUILayout.Space(5f);
  166. EditorGUILayout.LabelField("Compression", EditorStyles.boldLabel);
  167. EditorGUILayout.BeginVertical("box");
  168. {
  169. EditorGUILayout.BeginHorizontal();
  170. {
  171. EditorGUILayout.LabelField("AssetBundle Compression", GUILayout.Width(160f));
  172. m_Controller.AssetBundleCompression = (AssetBundleCompressionType)EditorGUILayout.EnumPopup(m_Controller.AssetBundleCompression);
  173. }
  174. EditorGUILayout.EndHorizontal();
  175. EditorGUILayout.BeginHorizontal();
  176. {
  177. EditorGUILayout.LabelField("Compression Helper", GUILayout.Width(160f));
  178. string[] names = m_Controller.GetCompressionHelperTypeNames();
  179. int selectedIndex = EditorGUILayout.Popup(m_CompressionHelperTypeNameIndex, names);
  180. if (selectedIndex != m_CompressionHelperTypeNameIndex)
  181. {
  182. m_CompressionHelperTypeNameIndex = selectedIndex;
  183. m_Controller.CompressionHelperTypeName = selectedIndex <= 0 ? string.Empty : names[selectedIndex];
  184. if (m_Controller.RefreshCompressionHelper())
  185. {
  186. Debug.Log("Set compression helper success.");
  187. }
  188. else
  189. {
  190. Debug.LogWarning("Set compression helper failure.");
  191. }
  192. }
  193. }
  194. EditorGUILayout.EndHorizontal();
  195. EditorGUILayout.BeginHorizontal();
  196. {
  197. EditorGUILayout.LabelField("Additional Compression", GUILayout.Width(160f));
  198. m_Controller.AdditionalCompressionSelected = EditorGUILayout.ToggleLeft("Additional Compression for Output Full Resources with Compression Helper", m_Controller.AdditionalCompressionSelected);
  199. }
  200. EditorGUILayout.EndHorizontal();
  201. }
  202. EditorGUILayout.EndVertical();
  203. GUILayout.Space(5f);
  204. EditorGUILayout.LabelField("Build", EditorStyles.boldLabel);
  205. EditorGUILayout.BeginVertical("box");
  206. {
  207. EditorGUILayout.BeginHorizontal();
  208. {
  209. EditorGUILayout.LabelField("Force Rebuild AssetBundle", GUILayout.Width(160f));
  210. m_Controller.ForceRebuildAssetBundleSelected = EditorGUILayout.Toggle(m_Controller.ForceRebuildAssetBundleSelected);
  211. }
  212. EditorGUILayout.EndHorizontal();
  213. EditorGUILayout.BeginHorizontal();
  214. {
  215. EditorGUILayout.LabelField("Build Event Handler", GUILayout.Width(160f));
  216. string[] names = m_Controller.GetBuildEventHandlerTypeNames();
  217. int selectedIndex = EditorGUILayout.Popup(m_BuildEventHandlerTypeNameIndex, names);
  218. if (selectedIndex != m_BuildEventHandlerTypeNameIndex)
  219. {
  220. m_BuildEventHandlerTypeNameIndex = selectedIndex;
  221. m_Controller.BuildEventHandlerTypeName = selectedIndex <= 0 ? string.Empty : names[selectedIndex];
  222. if (m_Controller.RefreshBuildEventHandler())
  223. {
  224. Debug.Log("Set build event handler success.");
  225. }
  226. else
  227. {
  228. Debug.LogWarning("Set build event handler failure.");
  229. }
  230. }
  231. }
  232. EditorGUILayout.EndHorizontal();
  233. EditorGUILayout.BeginHorizontal();
  234. {
  235. EditorGUILayout.LabelField("Internal Resource Version", GUILayout.Width(160f));
  236. m_Controller.InternalResourceVersion = EditorGUILayout.IntField(m_Controller.InternalResourceVersion);
  237. }
  238. EditorGUILayout.EndHorizontal();
  239. EditorGUILayout.BeginHorizontal();
  240. {
  241. EditorGUILayout.LabelField("Resource Version", GUILayout.Width(160f));
  242. GUILayout.Label(Utility.Text.Format("{0} ({1})", m_Controller.ApplicableGameVersion, m_Controller.InternalResourceVersion.ToString()));
  243. }
  244. EditorGUILayout.EndHorizontal();
  245. EditorGUILayout.BeginHorizontal();
  246. {
  247. EditorGUILayout.LabelField("Output Directory", GUILayout.Width(160f));
  248. m_Controller.OutputDirectory = EditorGUILayout.TextField(m_Controller.OutputDirectory);
  249. if (GUILayout.Button("Browse...", GUILayout.Width(80f)))
  250. {
  251. BrowseOutputDirectory();
  252. }
  253. }
  254. EditorGUILayout.EndHorizontal();
  255. EditorGUILayout.BeginHorizontal();
  256. {
  257. EditorGUILayout.LabelField("Working Path", GUILayout.Width(160f));
  258. GUILayout.Label(m_Controller.WorkingPath);
  259. }
  260. EditorGUILayout.EndHorizontal();
  261. EditorGUILayout.BeginHorizontal();
  262. {
  263. EditorGUI.BeginDisabledGroup(!m_Controller.OutputPackageSelected);
  264. EditorGUILayout.LabelField("Output Package Path", GUILayout.Width(160f));
  265. GUILayout.Label(m_Controller.OutputPackagePath);
  266. EditorGUI.EndDisabledGroup();
  267. m_Controller.OutputPackageSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputPackageSelected, GUILayout.Width(70f));
  268. }
  269. EditorGUILayout.EndHorizontal();
  270. EditorGUILayout.BeginHorizontal();
  271. {
  272. EditorGUI.BeginDisabledGroup(!m_Controller.OutputFullSelected);
  273. EditorGUILayout.LabelField("Output Full Path", GUILayout.Width(160f));
  274. GUILayout.Label(m_Controller.OutputFullPath);
  275. EditorGUI.EndDisabledGroup();
  276. m_Controller.OutputFullSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputFullSelected, GUILayout.Width(70f));
  277. }
  278. EditorGUILayout.EndHorizontal();
  279. EditorGUILayout.BeginHorizontal();
  280. {
  281. EditorGUI.BeginDisabledGroup(!m_Controller.OutputPackedSelected);
  282. EditorGUILayout.LabelField("Output Packed Path", GUILayout.Width(160f));
  283. GUILayout.Label(m_Controller.OutputPackedPath);
  284. EditorGUI.EndDisabledGroup();
  285. m_Controller.OutputPackedSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputPackedSelected, GUILayout.Width(70f));
  286. }
  287. EditorGUILayout.EndHorizontal();
  288. EditorGUILayout.BeginHorizontal();
  289. {
  290. EditorGUILayout.LabelField("Build Report Path", GUILayout.Width(160f));
  291. GUILayout.Label(m_Controller.BuildReportPath);
  292. }
  293. EditorGUILayout.EndHorizontal();
  294. }
  295. EditorGUILayout.EndVertical();
  296. string buildMessage = string.Empty;
  297. MessageType buildMessageType = MessageType.None;
  298. GetBuildMessage(out buildMessage, out buildMessageType);
  299. EditorGUILayout.HelpBox(buildMessage, buildMessageType);
  300. GUILayout.Space(2f);
  301. EditorGUILayout.BeginHorizontal();
  302. {
  303. EditorGUI.BeginDisabledGroup(m_Controller.Platforms == Platform.Undefined || string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName) || !m_Controller.IsValidOutputDirectory);
  304. {
  305. if (GUILayout.Button("Start Build Resources"))
  306. {
  307. m_OrderBuildResources = true;
  308. }
  309. }
  310. EditorGUI.EndDisabledGroup();
  311. if (GUILayout.Button("Save", GUILayout.Width(80f)))
  312. {
  313. SaveConfiguration();
  314. }
  315. }
  316. EditorGUILayout.EndHorizontal();
  317. }
  318. EditorGUILayout.EndVertical();
  319. }
  320. private void BrowseOutputDirectory()
  321. {
  322. string directory = EditorUtility.OpenFolderPanel("Select Output Directory", m_Controller.OutputDirectory, string.Empty);
  323. if (!string.IsNullOrEmpty(directory))
  324. {
  325. m_Controller.OutputDirectory = directory;
  326. }
  327. }
  328. private void GetBuildMessage(out string message, out MessageType messageType)
  329. {
  330. message = string.Empty;
  331. messageType = MessageType.Error;
  332. if (m_Controller.Platforms == Platform.Undefined)
  333. {
  334. if (!string.IsNullOrEmpty(message))
  335. {
  336. message += Environment.NewLine;
  337. }
  338. message += "Platform is invalid.";
  339. }
  340. if (string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName))
  341. {
  342. if (!string.IsNullOrEmpty(message))
  343. {
  344. message += Environment.NewLine;
  345. }
  346. message += "Compression helper is invalid.";
  347. }
  348. if (!m_Controller.IsValidOutputDirectory)
  349. {
  350. if (!string.IsNullOrEmpty(message))
  351. {
  352. message += Environment.NewLine;
  353. }
  354. message += "Output directory is invalid.";
  355. }
  356. if (!string.IsNullOrEmpty(message))
  357. {
  358. return;
  359. }
  360. messageType = MessageType.Info;
  361. if (Directory.Exists(m_Controller.OutputPackagePath))
  362. {
  363. message += Utility.Text.Format("{0} will be overwritten.", m_Controller.OutputPackagePath);
  364. messageType = MessageType.Warning;
  365. }
  366. if (Directory.Exists(m_Controller.OutputFullPath))
  367. {
  368. if (message.Length > 0)
  369. {
  370. message += " ";
  371. }
  372. message += Utility.Text.Format("{0} will be overwritten.", m_Controller.OutputFullPath);
  373. messageType = MessageType.Warning;
  374. }
  375. if (Directory.Exists(m_Controller.OutputPackedPath))
  376. {
  377. if (message.Length > 0)
  378. {
  379. message += " ";
  380. }
  381. message += Utility.Text.Format("{0} will be overwritten.", m_Controller.OutputPackedPath);
  382. messageType = MessageType.Warning;
  383. }
  384. if (messageType == MessageType.Warning)
  385. {
  386. return;
  387. }
  388. message = "Ready to build.";
  389. }
  390. private void BuildResources()
  391. {
  392. if (m_Controller.BuildResources())
  393. {
  394. Debug.Log("Build resources success.");
  395. SaveConfiguration();
  396. }
  397. else
  398. {
  399. Debug.LogWarning("Build resources failure.");
  400. }
  401. }
  402. private void SaveConfiguration()
  403. {
  404. if (m_Controller.Save())
  405. {
  406. Debug.Log("Save configuration success.");
  407. }
  408. else
  409. {
  410. Debug.LogWarning("Save configuration failure.");
  411. }
  412. }
  413. private void DrawPlatform(Platform platform, string platformName)
  414. {
  415. m_Controller.SelectPlatform(platform, EditorGUILayout.ToggleLeft(platformName, m_Controller.IsPlatformSelected(platform)));
  416. }
  417. private void OnLoadingResource(int index, int count)
  418. {
  419. EditorUtility.DisplayProgressBar("Loading Resources", Utility.Text.Format("Loading resources, {0}/{1} loaded.", index.ToString(), count.ToString()), (float)index / count);
  420. }
  421. private void OnLoadingAsset(int index, int count)
  422. {
  423. EditorUtility.DisplayProgressBar("Loading Assets", Utility.Text.Format("Loading assets, {0}/{1} loaded.", index.ToString(), count.ToString()), (float)index / count);
  424. }
  425. private void OnLoadCompleted()
  426. {
  427. EditorUtility.ClearProgressBar();
  428. }
  429. private void OnAnalyzingAsset(int index, int count)
  430. {
  431. EditorUtility.DisplayProgressBar("Analyzing Assets", Utility.Text.Format("Analyzing assets, {0}/{1} analyzed.", index.ToString(), count.ToString()), (float)index / count);
  432. }
  433. private void OnAnalyzeCompleted()
  434. {
  435. EditorUtility.ClearProgressBar();
  436. }
  437. private bool OnProcessingAssetBundle(string assetBundleName, float progress)
  438. {
  439. if (EditorUtility.DisplayCancelableProgressBar("Processing AssetBundle", Utility.Text.Format("Processing '{0}'...", assetBundleName), progress))
  440. {
  441. EditorUtility.ClearProgressBar();
  442. return true;
  443. }
  444. else
  445. {
  446. Repaint();
  447. return false;
  448. }
  449. }
  450. private bool OnProcessingBinary(string binaryName, float progress)
  451. {
  452. if (EditorUtility.DisplayCancelableProgressBar("Processing Binary", Utility.Text.Format("Processing '{0}'...", binaryName), progress))
  453. {
  454. EditorUtility.ClearProgressBar();
  455. return true;
  456. }
  457. else
  458. {
  459. Repaint();
  460. return false;
  461. }
  462. }
  463. private void OnProcessResourceComplete(Platform platform)
  464. {
  465. EditorUtility.ClearProgressBar();
  466. Debug.Log(Utility.Text.Format("Build resources for '{0}' complete.", platform.ToString()));
  467. }
  468. private void OnBuildResourceError(string errorMessage)
  469. {
  470. EditorUtility.ClearProgressBar();
  471. Debug.LogWarning(Utility.Text.Format("Build resources error with error message '{0}'.", errorMessage));
  472. }
  473. }
  474. }