ResourceEditor.cs 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  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.Collections.Generic;
  9. using UnityEditor;
  10. using UnityEngine;
  11. namespace UnityGameFramework.Editor.ResourceTools
  12. {
  13. /// <summary>
  14. /// 资源编辑器。
  15. /// </summary>
  16. internal sealed partial class ResourceEditor : EditorWindow
  17. {
  18. private ResourceEditorController m_Controller = null;
  19. private MenuState m_MenuState = MenuState.Normal;
  20. private Resource m_SelectedResource = null;
  21. private ResourceFolder m_ResourceRoot = null;
  22. private HashSet<string> m_ExpandedResourceFolderNames = null;
  23. private HashSet<Asset> m_SelectedAssetsInSelectedResource = null;
  24. private HashSet<SourceFolder> m_ExpandedSourceFolders = null;
  25. private HashSet<SourceAsset> m_SelectedSourceAssets = null;
  26. private Texture m_MissingSourceAssetIcon = null;
  27. private HashSet<SourceFolder> m_CachedSelectedSourceFolders = null;
  28. private HashSet<SourceFolder> m_CachedUnselectedSourceFolders = null;
  29. private HashSet<SourceFolder> m_CachedAssignedSourceFolders = null;
  30. private HashSet<SourceFolder> m_CachedUnassignedSourceFolders = null;
  31. private HashSet<SourceAsset> m_CachedAssignedSourceAssets = null;
  32. private HashSet<SourceAsset> m_CachedUnassignedSourceAssets = null;
  33. private Vector2 m_ResourcesViewScroll = Vector2.zero;
  34. private Vector2 m_ResourceViewScroll = Vector2.zero;
  35. private Vector2 m_SourceAssetsViewScroll = Vector2.zero;
  36. private string m_InputResourceName = null;
  37. private string m_InputResourceVariant = null;
  38. private bool m_HideAssignedSourceAssets = false;
  39. private int m_CurrentResourceContentCount = 0;
  40. private int m_CurrentResourceRowOnDraw = 0;
  41. private int m_CurrentSourceRowOnDraw = 0;
  42. [MenuItem("Game Framework/Resource Tools/Resource Editor", false, 41)]
  43. private static void Open()
  44. {
  45. ResourceEditor window = GetWindow<ResourceEditor>("Resource Editor", true);
  46. window.minSize = new Vector2(1400f, 600f);
  47. }
  48. private void OnEnable()
  49. {
  50. m_Controller = new ResourceEditorController();
  51. m_Controller.OnLoadingResource += OnLoadingResource;
  52. m_Controller.OnLoadingAsset += OnLoadingAsset;
  53. m_Controller.OnLoadCompleted += OnLoadCompleted;
  54. m_Controller.OnAssetAssigned += OnAssetAssigned;
  55. m_Controller.OnAssetUnassigned += OnAssetUnassigned;
  56. m_MenuState = MenuState.Normal;
  57. m_SelectedResource = null;
  58. m_ResourceRoot = new ResourceFolder("Resources", null);
  59. m_ExpandedResourceFolderNames = new HashSet<string>();
  60. m_SelectedAssetsInSelectedResource = new HashSet<Asset>();
  61. m_ExpandedSourceFolders = new HashSet<SourceFolder>();
  62. m_SelectedSourceAssets = new HashSet<SourceAsset>();
  63. m_MissingSourceAssetIcon = EditorGUIUtility.IconContent("console.warnicon.sml").image;
  64. m_CachedSelectedSourceFolders = new HashSet<SourceFolder>();
  65. m_CachedUnselectedSourceFolders = new HashSet<SourceFolder>();
  66. m_CachedAssignedSourceFolders = new HashSet<SourceFolder>();
  67. m_CachedUnassignedSourceFolders = new HashSet<SourceFolder>();
  68. m_CachedAssignedSourceAssets = new HashSet<SourceAsset>();
  69. m_CachedUnassignedSourceAssets = new HashSet<SourceAsset>();
  70. m_ResourcesViewScroll = Vector2.zero;
  71. m_ResourceViewScroll = Vector2.zero;
  72. m_SourceAssetsViewScroll = Vector2.zero;
  73. m_InputResourceName = null;
  74. m_InputResourceVariant = null;
  75. m_HideAssignedSourceAssets = false;
  76. m_CurrentResourceContentCount = 0;
  77. m_CurrentResourceRowOnDraw = 0;
  78. m_CurrentSourceRowOnDraw = 0;
  79. if (m_Controller.Load())
  80. {
  81. Debug.Log("Load configuration success.");
  82. }
  83. else
  84. {
  85. Debug.LogWarning("Load configuration failure.");
  86. }
  87. EditorUtility.DisplayProgressBar("Prepare Resource Editor", "Processing...", 0f);
  88. RefreshResourceTree();
  89. EditorUtility.ClearProgressBar();
  90. }
  91. private void OnGUI()
  92. {
  93. EditorGUILayout.BeginHorizontal(GUILayout.Width(position.width), GUILayout.Height(position.height));
  94. {
  95. GUILayout.Space(2f);
  96. EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.25f));
  97. {
  98. GUILayout.Space(5f);
  99. EditorGUILayout.LabelField(Utility.Text.Format("Resource List ({0})", m_Controller.ResourceCount.ToString()), EditorStyles.boldLabel);
  100. EditorGUILayout.BeginHorizontal("box", GUILayout.Height(position.height - 52f));
  101. {
  102. DrawResourcesView();
  103. }
  104. EditorGUILayout.EndHorizontal();
  105. EditorGUILayout.BeginHorizontal();
  106. {
  107. GUILayout.Space(5f);
  108. DrawResourcesMenu();
  109. }
  110. EditorGUILayout.EndHorizontal();
  111. }
  112. EditorGUILayout.EndVertical();
  113. EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.25f));
  114. {
  115. GUILayout.Space(5f);
  116. EditorGUILayout.LabelField(Utility.Text.Format("Resource Content ({0})", m_CurrentResourceContentCount.ToString()), EditorStyles.boldLabel);
  117. EditorGUILayout.BeginHorizontal("box", GUILayout.Height(position.height - 52f));
  118. {
  119. DrawResourceView();
  120. }
  121. EditorGUILayout.EndHorizontal();
  122. EditorGUILayout.BeginHorizontal();
  123. {
  124. GUILayout.Space(5f);
  125. DrawResourceMenu();
  126. }
  127. EditorGUILayout.EndHorizontal();
  128. }
  129. EditorGUILayout.EndVertical();
  130. EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.5f - 16f));
  131. {
  132. GUILayout.Space(5f);
  133. EditorGUILayout.LabelField("Asset List", EditorStyles.boldLabel);
  134. EditorGUILayout.BeginHorizontal("box", GUILayout.Height(position.height - 52f));
  135. {
  136. DrawSourceAssetsView();
  137. }
  138. EditorGUILayout.EndHorizontal();
  139. EditorGUILayout.BeginHorizontal();
  140. {
  141. GUILayout.Space(5f);
  142. DrawSourceAssetsMenu();
  143. }
  144. EditorGUILayout.EndHorizontal();
  145. }
  146. EditorGUILayout.EndVertical();
  147. GUILayout.Space(5f);
  148. }
  149. EditorGUILayout.EndHorizontal();
  150. }
  151. private void DrawResourcesView()
  152. {
  153. m_CurrentResourceRowOnDraw = 0;
  154. m_ResourcesViewScroll = EditorGUILayout.BeginScrollView(m_ResourcesViewScroll);
  155. {
  156. DrawResourceFolder(m_ResourceRoot);
  157. }
  158. EditorGUILayout.EndScrollView();
  159. }
  160. private void DrawResourceFolder(ResourceFolder folder)
  161. {
  162. bool expand = IsExpandedResourceFolder(folder);
  163. EditorGUILayout.BeginHorizontal();
  164. {
  165. #if UNITY_2019_3_OR_NEWER
  166. bool foldout = EditorGUI.Foldout(new Rect(18f + 14f * folder.Depth, 20f * m_CurrentResourceRowOnDraw + 4f, int.MaxValue, 14f), expand, string.Empty, true);
  167. #else
  168. bool foldout = EditorGUI.Foldout(new Rect(18f + 14f * folder.Depth, 20f * m_CurrentResourceRowOnDraw + 2f, int.MaxValue, 14f), expand, string.Empty, true);
  169. #endif
  170. if (expand != foldout)
  171. {
  172. expand = !expand;
  173. SetExpandedResourceFolder(folder, expand);
  174. }
  175. #if UNITY_2019_3_OR_NEWER
  176. GUI.DrawTexture(new Rect(32f + 14f * folder.Depth, 20f * m_CurrentResourceRowOnDraw + 3f, 16f, 16f), ResourceFolder.Icon);
  177. EditorGUILayout.LabelField(string.Empty, GUILayout.Width(44f + 14f * folder.Depth), GUILayout.Height(18f));
  178. #else
  179. GUI.DrawTexture(new Rect(32f + 14f * folder.Depth, 20f * m_CurrentResourceRowOnDraw + 1f, 16f, 16f), ResourceFolder.Icon);
  180. EditorGUILayout.LabelField(string.Empty, GUILayout.Width(40f + 14f * folder.Depth), GUILayout.Height(18f));
  181. #endif
  182. EditorGUILayout.LabelField(folder.Name);
  183. }
  184. EditorGUILayout.EndHorizontal();
  185. m_CurrentResourceRowOnDraw++;
  186. if (expand)
  187. {
  188. foreach (ResourceFolder subFolder in folder.GetFolders())
  189. {
  190. DrawResourceFolder(subFolder);
  191. }
  192. foreach (ResourceItem resourceItem in folder.GetItems())
  193. {
  194. DrawResourceItem(resourceItem);
  195. }
  196. }
  197. }
  198. private void DrawResourceItem(ResourceItem resourceItem)
  199. {
  200. EditorGUILayout.BeginHorizontal();
  201. {
  202. string title = resourceItem.Name;
  203. if (resourceItem.Resource.Packed)
  204. {
  205. title = "[Packed] " + title;
  206. }
  207. float emptySpace = position.width;
  208. if (EditorGUILayout.Toggle(m_SelectedResource == resourceItem.Resource, GUILayout.Width(emptySpace - 12f)))
  209. {
  210. ChangeSelectedResource(resourceItem.Resource);
  211. }
  212. else if (m_SelectedResource == resourceItem.Resource)
  213. {
  214. ChangeSelectedResource(null);
  215. }
  216. GUILayout.Space(-emptySpace + 24f);
  217. #if UNITY_2019_3_OR_NEWER
  218. GUI.DrawTexture(new Rect(32f + 14f * resourceItem.Depth, 20f * m_CurrentResourceRowOnDraw + 3f, 16f, 16f), resourceItem.Icon);
  219. EditorGUILayout.LabelField(string.Empty, GUILayout.Width(30f + 14f * resourceItem.Depth), GUILayout.Height(18f));
  220. #else
  221. GUI.DrawTexture(new Rect(32f + 14f * resourceItem.Depth, 20f * m_CurrentResourceRowOnDraw + 1f, 16f, 16f), resourceItem.Icon);
  222. EditorGUILayout.LabelField(string.Empty, GUILayout.Width(26f + 14f * resourceItem.Depth), GUILayout.Height(18f));
  223. #endif
  224. EditorGUILayout.LabelField(title);
  225. }
  226. EditorGUILayout.EndHorizontal();
  227. m_CurrentResourceRowOnDraw++;
  228. }
  229. private void DrawResourcesMenu()
  230. {
  231. switch (m_MenuState)
  232. {
  233. case MenuState.Normal:
  234. DrawResourcesMenu_Normal();
  235. break;
  236. case MenuState.Add:
  237. DrawResourcesMenu_Add();
  238. break;
  239. case MenuState.Rename:
  240. DrawResourcesMenu_Rename();
  241. break;
  242. case MenuState.Remove:
  243. DrawResourcesMenu_Remove();
  244. break;
  245. }
  246. }
  247. private void DrawResourcesMenu_Normal()
  248. {
  249. if (GUILayout.Button("Add", GUILayout.Width(65f)))
  250. {
  251. m_MenuState = MenuState.Add;
  252. m_InputResourceName = null;
  253. m_InputResourceVariant = null;
  254. GUI.FocusControl(null);
  255. }
  256. EditorGUI.BeginDisabledGroup(m_SelectedResource == null);
  257. {
  258. if (GUILayout.Button("Rename", GUILayout.Width(65f)))
  259. {
  260. m_MenuState = MenuState.Rename;
  261. m_InputResourceName = m_SelectedResource != null ? m_SelectedResource.Name : null;
  262. m_InputResourceVariant = m_SelectedResource != null ? m_SelectedResource.Variant : null;
  263. GUI.FocusControl(null);
  264. }
  265. if (GUILayout.Button("Remove", GUILayout.Width(65f)))
  266. {
  267. m_MenuState = MenuState.Remove;
  268. }
  269. if (m_SelectedResource == null)
  270. {
  271. EditorGUILayout.EnumPopup(LoadType.LoadFromFile);
  272. }
  273. else
  274. {
  275. LoadType loadType = (LoadType)EditorGUILayout.EnumPopup(m_SelectedResource.LoadType);
  276. if (loadType != m_SelectedResource.LoadType)
  277. {
  278. SetResourceLoadType(loadType);
  279. }
  280. }
  281. bool packed = EditorGUILayout.ToggleLeft("Packed", m_SelectedResource != null && m_SelectedResource.Packed, GUILayout.Width(65f));
  282. if (m_SelectedResource != null && packed != m_SelectedResource.Packed)
  283. {
  284. SetResourcePacked(packed);
  285. }
  286. }
  287. EditorGUI.EndDisabledGroup();
  288. }
  289. private void DrawResourcesMenu_Add()
  290. {
  291. GUI.SetNextControlName("NewResourceNameTextField");
  292. m_InputResourceName = EditorGUILayout.TextField(m_InputResourceName);
  293. GUI.SetNextControlName("NewResourceVariantTextField");
  294. m_InputResourceVariant = EditorGUILayout.TextField(m_InputResourceVariant, GUILayout.Width(60f));
  295. if (GUI.GetNameOfFocusedControl() == "NewResourceNameTextField" || GUI.GetNameOfFocusedControl() == "NewResourceVariantTextField")
  296. {
  297. if (Event.current.isKey && Event.current.keyCode == KeyCode.Return)
  298. {
  299. EditorUtility.DisplayProgressBar("Add Resource", "Processing...", 0f);
  300. AddResource(m_InputResourceName, m_InputResourceVariant, true);
  301. EditorUtility.ClearProgressBar();
  302. Repaint();
  303. }
  304. }
  305. if (GUILayout.Button("Add", GUILayout.Width(50f)))
  306. {
  307. EditorUtility.DisplayProgressBar("Add Resource", "Processing...", 0f);
  308. AddResource(m_InputResourceName, m_InputResourceVariant, true);
  309. EditorUtility.ClearProgressBar();
  310. }
  311. if (GUILayout.Button("Back", GUILayout.Width(50f)))
  312. {
  313. m_MenuState = MenuState.Normal;
  314. }
  315. }
  316. private void DrawResourcesMenu_Rename()
  317. {
  318. if (m_SelectedResource == null)
  319. {
  320. m_MenuState = MenuState.Normal;
  321. return;
  322. }
  323. GUI.SetNextControlName("RenameResourceNameTextField");
  324. m_InputResourceName = EditorGUILayout.TextField(m_InputResourceName);
  325. GUI.SetNextControlName("RenameResourceVariantTextField");
  326. m_InputResourceVariant = EditorGUILayout.TextField(m_InputResourceVariant, GUILayout.Width(60f));
  327. if (GUI.GetNameOfFocusedControl() == "RenameResourceNameTextField" || GUI.GetNameOfFocusedControl() == "RenameResourceVariantTextField")
  328. {
  329. if (Event.current.isKey && Event.current.keyCode == KeyCode.Return)
  330. {
  331. EditorUtility.DisplayProgressBar("Rename Resource", "Processing...", 0f);
  332. RenameResource(m_SelectedResource, m_InputResourceName, m_InputResourceVariant);
  333. EditorUtility.ClearProgressBar();
  334. Repaint();
  335. }
  336. }
  337. if (GUILayout.Button("OK", GUILayout.Width(50f)))
  338. {
  339. EditorUtility.DisplayProgressBar("Rename Resource", "Processing...", 0f);
  340. RenameResource(m_SelectedResource, m_InputResourceName, m_InputResourceVariant);
  341. EditorUtility.ClearProgressBar();
  342. }
  343. if (GUILayout.Button("Back", GUILayout.Width(50f)))
  344. {
  345. m_MenuState = MenuState.Normal;
  346. }
  347. }
  348. private void DrawResourcesMenu_Remove()
  349. {
  350. if (m_SelectedResource == null)
  351. {
  352. m_MenuState = MenuState.Normal;
  353. return;
  354. }
  355. GUILayout.Label(Utility.Text.Format("Remove '{0}' ?", m_SelectedResource.FullName));
  356. if (GUILayout.Button("Yes", GUILayout.Width(50f)))
  357. {
  358. EditorUtility.DisplayProgressBar("Remove Resource", "Processing...", 0f);
  359. RemoveResource();
  360. EditorUtility.ClearProgressBar();
  361. m_MenuState = MenuState.Normal;
  362. }
  363. if (GUILayout.Button("No", GUILayout.Width(50f)))
  364. {
  365. m_MenuState = MenuState.Normal;
  366. }
  367. }
  368. private void DrawResourceView()
  369. {
  370. m_ResourceViewScroll = EditorGUILayout.BeginScrollView(m_ResourceViewScroll);
  371. {
  372. if (m_SelectedResource != null)
  373. {
  374. int index = 0;
  375. Asset[] assets = m_Controller.GetAssets(m_SelectedResource.Name, m_SelectedResource.Variant);
  376. m_CurrentResourceContentCount = assets.Length;
  377. foreach (Asset asset in assets)
  378. {
  379. SourceAsset sourceAsset = m_Controller.GetSourceAsset(asset.Guid);
  380. string assetName = sourceAsset != null ? (m_Controller.AssetSorter == AssetSorterType.Path ? sourceAsset.Path : (m_Controller.AssetSorter == AssetSorterType.Name ? sourceAsset.Name : sourceAsset.Guid)) : asset.Guid;
  381. EditorGUILayout.BeginHorizontal();
  382. {
  383. float emptySpace = position.width;
  384. bool select = IsSelectedAssetInSelectedResource(asset);
  385. if (select != EditorGUILayout.Toggle(select, GUILayout.Width(emptySpace - 12f)))
  386. {
  387. select = !select;
  388. SetSelectedAssetInSelectedResource(asset, select);
  389. }
  390. GUILayout.Space(-emptySpace + 24f);
  391. #if UNITY_2019_3_OR_NEWER
  392. GUI.DrawTexture(new Rect(20f, 20f * index++ + 3f, 16f, 16f), sourceAsset != null ? sourceAsset.Icon : m_MissingSourceAssetIcon);
  393. EditorGUILayout.LabelField(string.Empty, GUILayout.Width(16f), GUILayout.Height(18f));
  394. #else
  395. GUI.DrawTexture(new Rect(20f, 20f * index++ + 1f, 16f, 16f), sourceAsset != null ? sourceAsset.Icon : m_MissingSourceAssetIcon);
  396. EditorGUILayout.LabelField(string.Empty, GUILayout.Width(14f), GUILayout.Height(18f));
  397. #endif
  398. EditorGUILayout.LabelField(assetName);
  399. }
  400. EditorGUILayout.EndHorizontal();
  401. }
  402. }
  403. else
  404. {
  405. m_CurrentResourceContentCount = 0;
  406. }
  407. }
  408. EditorGUILayout.EndScrollView();
  409. }
  410. private void DrawResourceMenu()
  411. {
  412. if (GUILayout.Button("All", GUILayout.Width(50f)) && m_SelectedResource != null)
  413. {
  414. Asset[] assets = m_Controller.GetAssets(m_SelectedResource.Name, m_SelectedResource.Variant);
  415. foreach (Asset asset in assets)
  416. {
  417. SetSelectedAssetInSelectedResource(asset, true);
  418. }
  419. }
  420. if (GUILayout.Button("None", GUILayout.Width(50f)))
  421. {
  422. m_SelectedAssetsInSelectedResource.Clear();
  423. }
  424. m_Controller.AssetSorter = (AssetSorterType)EditorGUILayout.EnumPopup(m_Controller.AssetSorter, GUILayout.Width(60f));
  425. GUILayout.Label(string.Empty);
  426. EditorGUI.BeginDisabledGroup(m_SelectedResource == null || m_SelectedAssetsInSelectedResource.Count <= 0);
  427. {
  428. if (GUILayout.Button(Utility.Text.Format("{0} >>", m_SelectedAssetsInSelectedResource.Count.ToString()), GUILayout.Width(80f)))
  429. {
  430. foreach (Asset asset in m_SelectedAssetsInSelectedResource)
  431. {
  432. UnassignAsset(asset);
  433. }
  434. m_SelectedAssetsInSelectedResource.Clear();
  435. }
  436. }
  437. EditorGUI.EndDisabledGroup();
  438. }
  439. private void DrawSourceAssetsView()
  440. {
  441. m_CurrentSourceRowOnDraw = 0;
  442. m_SourceAssetsViewScroll = EditorGUILayout.BeginScrollView(m_SourceAssetsViewScroll);
  443. {
  444. DrawSourceFolder(m_Controller.SourceAssetRoot);
  445. }
  446. EditorGUILayout.EndScrollView();
  447. }
  448. private void DrawSourceAssetsMenu()
  449. {
  450. HashSet<SourceAsset> selectedSourceAssets = GetSelectedSourceAssets();
  451. EditorGUI.BeginDisabledGroup(m_SelectedResource == null || selectedSourceAssets.Count <= 0);
  452. {
  453. if (GUILayout.Button(Utility.Text.Format("<< {0}", selectedSourceAssets.Count.ToString()), GUILayout.Width(80f)))
  454. {
  455. foreach (SourceAsset sourceAsset in selectedSourceAssets)
  456. {
  457. AssignAsset(sourceAsset, m_SelectedResource);
  458. }
  459. m_SelectedSourceAssets.Clear();
  460. m_CachedSelectedSourceFolders.Clear();
  461. }
  462. }
  463. EditorGUI.EndDisabledGroup();
  464. EditorGUI.BeginDisabledGroup(selectedSourceAssets.Count <= 0);
  465. {
  466. if (GUILayout.Button(Utility.Text.Format("<<< {0}", selectedSourceAssets.Count.ToString()), GUILayout.Width(80f)))
  467. {
  468. int index = 0;
  469. int count = selectedSourceAssets.Count;
  470. foreach (SourceAsset sourceAsset in selectedSourceAssets)
  471. {
  472. EditorUtility.DisplayProgressBar("Add Resources", Utility.Text.Format("{0}/{1} processing...", (++index).ToString(), count.ToString()), (float)index / count);
  473. int dotIndex = sourceAsset.FromRootPath.IndexOf('.');
  474. string name = dotIndex > 0 ? sourceAsset.FromRootPath.Substring(0, dotIndex) : sourceAsset.FromRootPath;
  475. AddResource(name, null, false);
  476. Resource resource = m_Controller.GetResource(name, null);
  477. if (resource == null)
  478. {
  479. continue;
  480. }
  481. AssignAsset(sourceAsset, resource);
  482. }
  483. EditorUtility.DisplayProgressBar("Add Resources", "Complete processing...", 1f);
  484. RefreshResourceTree();
  485. EditorUtility.ClearProgressBar();
  486. m_SelectedSourceAssets.Clear();
  487. m_CachedSelectedSourceFolders.Clear();
  488. }
  489. }
  490. EditorGUI.EndDisabledGroup();
  491. bool hideAssignedSourceAssets = EditorGUILayout.ToggleLeft("Hide Assigned", m_HideAssignedSourceAssets, GUILayout.Width(100f));
  492. if (hideAssignedSourceAssets != m_HideAssignedSourceAssets)
  493. {
  494. m_HideAssignedSourceAssets = hideAssignedSourceAssets;
  495. m_CachedSelectedSourceFolders.Clear();
  496. m_CachedUnselectedSourceFolders.Clear();
  497. m_CachedAssignedSourceFolders.Clear();
  498. m_CachedUnassignedSourceFolders.Clear();
  499. }
  500. GUILayout.Label(string.Empty);
  501. if (GUILayout.Button("Clean", GUILayout.Width(80f)))
  502. {
  503. EditorUtility.DisplayProgressBar("Clean", "Processing...", 0f);
  504. CleanResource();
  505. EditorUtility.ClearProgressBar();
  506. }
  507. if (GUILayout.Button("Save", GUILayout.Width(80f)))
  508. {
  509. EditorUtility.DisplayProgressBar("Save", "Processing...", 0f);
  510. SaveConfiguration();
  511. EditorUtility.ClearProgressBar();
  512. }
  513. }
  514. private void DrawSourceFolder(SourceFolder sourceFolder)
  515. {
  516. if (m_HideAssignedSourceAssets && IsAssignedSourceFolder(sourceFolder))
  517. {
  518. return;
  519. }
  520. bool expand = IsExpandedSourceFolder(sourceFolder);
  521. EditorGUILayout.BeginHorizontal();
  522. {
  523. bool select = IsSelectedSourceFolder(sourceFolder);
  524. if (select != EditorGUILayout.Toggle(select, GUILayout.Width(12f + 14f * sourceFolder.Depth)))
  525. {
  526. select = !select;
  527. SetSelectedSourceFolder(sourceFolder, select);
  528. }
  529. GUILayout.Space(-14f * sourceFolder.Depth);
  530. #if UNITY_2019_3_OR_NEWER
  531. bool foldout = EditorGUI.Foldout(new Rect(18f + 14f * sourceFolder.Depth, 20f * m_CurrentSourceRowOnDraw + 4f, int.MaxValue, 14f), expand, string.Empty, true);
  532. #else
  533. bool foldout = EditorGUI.Foldout(new Rect(18f + 14f * sourceFolder.Depth, 20f * m_CurrentSourceRowOnDraw + 2f, int.MaxValue, 14f), expand, string.Empty, true);
  534. #endif
  535. if (expand != foldout)
  536. {
  537. expand = !expand;
  538. SetExpandedSourceFolder(sourceFolder, expand);
  539. }
  540. #if UNITY_2019_3_OR_NEWER
  541. GUI.DrawTexture(new Rect(32f + 14f * sourceFolder.Depth, 20f * m_CurrentSourceRowOnDraw + 3f, 16f, 16f), SourceFolder.Icon);
  542. EditorGUILayout.LabelField(string.Empty, GUILayout.Width(30f + 14f * sourceFolder.Depth), GUILayout.Height(18f));
  543. #else
  544. GUI.DrawTexture(new Rect(32f + 14f * sourceFolder.Depth, 20f * m_CurrentSourceRowOnDraw + 1f, 16f, 16f), SourceFolder.Icon);
  545. EditorGUILayout.LabelField(string.Empty, GUILayout.Width(26f + 14f * sourceFolder.Depth), GUILayout.Height(18f));
  546. #endif
  547. EditorGUILayout.LabelField(sourceFolder.Name);
  548. }
  549. EditorGUILayout.EndHorizontal();
  550. m_CurrentSourceRowOnDraw++;
  551. if (expand)
  552. {
  553. foreach (SourceFolder subSourceFolder in sourceFolder.GetFolders())
  554. {
  555. DrawSourceFolder(subSourceFolder);
  556. }
  557. foreach (SourceAsset sourceAsset in sourceFolder.GetAssets())
  558. {
  559. DrawSourceAsset(sourceAsset);
  560. }
  561. }
  562. }
  563. private void DrawSourceAsset(SourceAsset sourceAsset)
  564. {
  565. if (m_HideAssignedSourceAssets && IsAssignedSourceAsset(sourceAsset))
  566. {
  567. return;
  568. }
  569. EditorGUILayout.BeginHorizontal();
  570. {
  571. float emptySpace = position.width;
  572. bool select = IsSelectedSourceAsset(sourceAsset);
  573. if (select != EditorGUILayout.Toggle(select, GUILayout.Width(emptySpace - 12f)))
  574. {
  575. select = !select;
  576. SetSelectedSourceAsset(sourceAsset, select);
  577. }
  578. GUILayout.Space(-emptySpace + 24f);
  579. #if UNITY_2019_3_OR_NEWER
  580. GUI.DrawTexture(new Rect(32f + 14f * sourceAsset.Depth, 20f * m_CurrentSourceRowOnDraw + 3f, 16f, 16f), sourceAsset.Icon);
  581. EditorGUILayout.LabelField(string.Empty, GUILayout.Width(30f + 14f * sourceAsset.Depth), GUILayout.Height(18f));
  582. #else
  583. GUI.DrawTexture(new Rect(32f + 14f * sourceAsset.Depth, 20f * m_CurrentSourceRowOnDraw + 1f, 16f, 16f), sourceAsset.Icon);
  584. EditorGUILayout.LabelField(string.Empty, GUILayout.Width(26f + 14f * sourceAsset.Depth), GUILayout.Height(18f));
  585. #endif
  586. EditorGUILayout.LabelField(sourceAsset.Name);
  587. Asset asset = m_Controller.GetAsset(sourceAsset.Guid);
  588. EditorGUILayout.LabelField(asset != null ? GetResourceFullName(asset.Resource.Name, asset.Resource.Variant) : string.Empty, GUILayout.Width(position.width * 0.15f));
  589. }
  590. EditorGUILayout.EndHorizontal();
  591. m_CurrentSourceRowOnDraw++;
  592. }
  593. private void ChangeSelectedResource(Resource resource)
  594. {
  595. if (m_SelectedResource == resource)
  596. {
  597. return;
  598. }
  599. m_SelectedResource = resource;
  600. m_SelectedAssetsInSelectedResource.Clear();
  601. }
  602. private void SaveConfiguration()
  603. {
  604. if (m_Controller.Save())
  605. {
  606. Debug.Log("Save configuration success.");
  607. }
  608. else
  609. {
  610. Debug.LogWarning("Save configuration failure.");
  611. }
  612. }
  613. private void AddResource(string name, string variant, bool refresh)
  614. {
  615. if (variant == string.Empty)
  616. {
  617. variant = null;
  618. }
  619. string fullName = GetResourceFullName(name, variant);
  620. if (m_Controller.AddResource(name, variant, null, LoadType.LoadFromFile, false))
  621. {
  622. if (refresh)
  623. {
  624. RefreshResourceTree();
  625. }
  626. Debug.Log(Utility.Text.Format("Add resource '{0}' success.", fullName));
  627. m_MenuState = MenuState.Normal;
  628. }
  629. else
  630. {
  631. Debug.LogWarning(Utility.Text.Format("Add resource '{0}' failure.", fullName));
  632. }
  633. }
  634. private void RenameResource(Resource resource, string newName, string newVariant)
  635. {
  636. if (resource == null)
  637. {
  638. Debug.LogWarning("Resource is invalid.");
  639. return;
  640. }
  641. if (newVariant == string.Empty)
  642. {
  643. newVariant = null;
  644. }
  645. string oldFullName = resource.FullName;
  646. string newFullName = GetResourceFullName(newName, newVariant);
  647. if (m_Controller.RenameResource(resource.Name, resource.Variant, newName, newVariant))
  648. {
  649. RefreshResourceTree();
  650. Debug.Log(Utility.Text.Format("Rename resource '{0}' to '{1}' success.", oldFullName, newFullName));
  651. m_MenuState = MenuState.Normal;
  652. }
  653. else
  654. {
  655. Debug.LogWarning(Utility.Text.Format("Rename resource '{0}' to '{1}' failure.", oldFullName, newFullName));
  656. }
  657. }
  658. private void RemoveResource()
  659. {
  660. string fullName = m_SelectedResource.FullName;
  661. if (m_Controller.RemoveResource(m_SelectedResource.Name, m_SelectedResource.Variant))
  662. {
  663. ChangeSelectedResource(null);
  664. RefreshResourceTree();
  665. Debug.Log(Utility.Text.Format("Remove resource '{0}' success.", fullName));
  666. }
  667. else
  668. {
  669. Debug.LogWarning(Utility.Text.Format("Remove resource '{0}' failure.", fullName));
  670. }
  671. }
  672. private void SetResourceLoadType(LoadType loadType)
  673. {
  674. string fullName = m_SelectedResource.FullName;
  675. if (m_Controller.SetResourceLoadType(m_SelectedResource.Name, m_SelectedResource.Variant, loadType))
  676. {
  677. Debug.Log(Utility.Text.Format("Set resource '{0}' load type to '{1}' success.", fullName, loadType.ToString()));
  678. }
  679. else
  680. {
  681. Debug.LogWarning(Utility.Text.Format("Set resource '{0}' load type to '{1}' failure.", fullName, loadType.ToString()));
  682. }
  683. }
  684. private void SetResourcePacked(bool packed)
  685. {
  686. string fullName = m_SelectedResource.FullName;
  687. if (m_Controller.SetResourcePacked(m_SelectedResource.Name, m_SelectedResource.Variant, packed))
  688. {
  689. Debug.Log(Utility.Text.Format("{1} resource '{0}' success.", fullName, packed ? "Pack" : "Unpack"));
  690. }
  691. else
  692. {
  693. Debug.LogWarning(Utility.Text.Format("{1} resource '{0}' failure.", fullName, packed ? "Pack" : "Unpack"));
  694. }
  695. }
  696. private void AssignAsset(SourceAsset sourceAsset, Resource resource)
  697. {
  698. if (!m_Controller.AssignAsset(sourceAsset.Guid, resource.Name, resource.Variant))
  699. {
  700. Debug.LogWarning(Utility.Text.Format("Assign asset '{0}' to resource '{1}' failure.", sourceAsset.Name, resource.FullName));
  701. }
  702. }
  703. private void UnassignAsset(Asset asset)
  704. {
  705. if (!m_Controller.UnassignAsset(asset.Guid))
  706. {
  707. Debug.LogWarning(Utility.Text.Format("Unassign asset '{0}' from resource '{1}' failure.", asset.Guid, m_SelectedResource.FullName));
  708. }
  709. }
  710. private void CleanResource()
  711. {
  712. int unknownAssetCount = m_Controller.RemoveUnknownAssets();
  713. int unusedResourceCount = m_Controller.RemoveUnusedResources();
  714. RefreshResourceTree();
  715. Debug.Log(Utility.Text.Format("Clean complete, {0} unknown assets and {1} unused resources has been removed.", unknownAssetCount.ToString(), unusedResourceCount.ToString()));
  716. }
  717. private void RefreshResourceTree()
  718. {
  719. m_ResourceRoot.Clear();
  720. Resource[] resources = m_Controller.GetResources();
  721. foreach (Resource resource in resources)
  722. {
  723. string[] splitedPath = resource.Name.Split('/');
  724. ResourceFolder folder = m_ResourceRoot;
  725. for (int i = 0; i < splitedPath.Length - 1; i++)
  726. {
  727. ResourceFolder subFolder = folder.GetFolder(splitedPath[i]);
  728. folder = subFolder == null ? folder.AddFolder(splitedPath[i]) : subFolder;
  729. }
  730. string fullName = resource.Variant != null ? Utility.Text.Format("{0}.{1}", splitedPath[splitedPath.Length - 1], resource.Variant) : splitedPath[splitedPath.Length - 1];
  731. folder.AddItem(fullName, resource);
  732. }
  733. }
  734. private bool IsExpandedResourceFolder(ResourceFolder folder)
  735. {
  736. return m_ExpandedResourceFolderNames.Contains(folder.FromRootPath);
  737. }
  738. private void SetExpandedResourceFolder(ResourceFolder folder, bool expand)
  739. {
  740. if (expand)
  741. {
  742. m_ExpandedResourceFolderNames.Add(folder.FromRootPath);
  743. }
  744. else
  745. {
  746. m_ExpandedResourceFolderNames.Remove(folder.FromRootPath);
  747. }
  748. }
  749. private bool IsSelectedAssetInSelectedResource(Asset asset)
  750. {
  751. return m_SelectedAssetsInSelectedResource.Contains(asset);
  752. }
  753. private void SetSelectedAssetInSelectedResource(Asset asset, bool select)
  754. {
  755. if (select)
  756. {
  757. m_SelectedAssetsInSelectedResource.Add(asset);
  758. }
  759. else
  760. {
  761. m_SelectedAssetsInSelectedResource.Remove(asset);
  762. }
  763. }
  764. private bool IsExpandedSourceFolder(SourceFolder sourceFolder)
  765. {
  766. return m_ExpandedSourceFolders.Contains(sourceFolder);
  767. }
  768. private void SetExpandedSourceFolder(SourceFolder sourceFolder, bool expand)
  769. {
  770. if (expand)
  771. {
  772. m_ExpandedSourceFolders.Add(sourceFolder);
  773. }
  774. else
  775. {
  776. m_ExpandedSourceFolders.Remove(sourceFolder);
  777. }
  778. }
  779. private bool IsSelectedSourceFolder(SourceFolder sourceFolder)
  780. {
  781. if (m_CachedSelectedSourceFolders.Contains(sourceFolder))
  782. {
  783. return true;
  784. }
  785. if (m_CachedUnselectedSourceFolders.Contains(sourceFolder))
  786. {
  787. return false;
  788. }
  789. foreach (SourceAsset sourceAsset in sourceFolder.GetAssets())
  790. {
  791. if (m_HideAssignedSourceAssets && IsAssignedSourceAsset(sourceAsset))
  792. {
  793. continue;
  794. }
  795. if (!IsSelectedSourceAsset(sourceAsset))
  796. {
  797. m_CachedUnselectedSourceFolders.Add(sourceFolder);
  798. return false;
  799. }
  800. }
  801. foreach (SourceFolder subSourceFolder in sourceFolder.GetFolders())
  802. {
  803. if (m_HideAssignedSourceAssets && IsAssignedSourceFolder(sourceFolder))
  804. {
  805. continue;
  806. }
  807. if (!IsSelectedSourceFolder(subSourceFolder))
  808. {
  809. m_CachedUnselectedSourceFolders.Add(sourceFolder);
  810. return false;
  811. }
  812. }
  813. m_CachedSelectedSourceFolders.Add(sourceFolder);
  814. return true;
  815. }
  816. private void SetSelectedSourceFolder(SourceFolder sourceFolder, bool select)
  817. {
  818. if (select)
  819. {
  820. m_CachedSelectedSourceFolders.Add(sourceFolder);
  821. m_CachedUnselectedSourceFolders.Remove(sourceFolder);
  822. SourceFolder folder = sourceFolder;
  823. while (folder != null)
  824. {
  825. m_CachedUnselectedSourceFolders.Remove(folder);
  826. folder = folder.Folder;
  827. }
  828. }
  829. else
  830. {
  831. m_CachedSelectedSourceFolders.Remove(sourceFolder);
  832. m_CachedUnselectedSourceFolders.Add(sourceFolder);
  833. SourceFolder folder = sourceFolder;
  834. while (folder != null)
  835. {
  836. m_CachedSelectedSourceFolders.Remove(folder);
  837. folder = folder.Folder;
  838. }
  839. }
  840. foreach (SourceAsset sourceAsset in sourceFolder.GetAssets())
  841. {
  842. if (m_HideAssignedSourceAssets && IsAssignedSourceAsset(sourceAsset))
  843. {
  844. continue;
  845. }
  846. SetSelectedSourceAsset(sourceAsset, select);
  847. }
  848. foreach (SourceFolder subSourceFolder in sourceFolder.GetFolders())
  849. {
  850. if (m_HideAssignedSourceAssets && IsAssignedSourceFolder(subSourceFolder))
  851. {
  852. continue;
  853. }
  854. SetSelectedSourceFolder(subSourceFolder, select);
  855. }
  856. }
  857. private bool IsSelectedSourceAsset(SourceAsset sourceAsset)
  858. {
  859. return m_SelectedSourceAssets.Contains(sourceAsset);
  860. }
  861. private void SetSelectedSourceAsset(SourceAsset sourceAsset, bool select)
  862. {
  863. if (select)
  864. {
  865. m_SelectedSourceAssets.Add(sourceAsset);
  866. SourceFolder folder = sourceAsset.Folder;
  867. while (folder != null)
  868. {
  869. m_CachedUnselectedSourceFolders.Remove(folder);
  870. folder = folder.Folder;
  871. }
  872. }
  873. else
  874. {
  875. m_SelectedSourceAssets.Remove(sourceAsset);
  876. SourceFolder folder = sourceAsset.Folder;
  877. while (folder != null)
  878. {
  879. m_CachedSelectedSourceFolders.Remove(folder);
  880. folder = folder.Folder;
  881. }
  882. }
  883. }
  884. private bool IsAssignedSourceAsset(SourceAsset sourceAsset)
  885. {
  886. if (m_CachedAssignedSourceAssets.Contains(sourceAsset))
  887. {
  888. return true;
  889. }
  890. if (m_CachedUnassignedSourceAssets.Contains(sourceAsset))
  891. {
  892. return false;
  893. }
  894. return m_Controller.GetAsset(sourceAsset.Guid) != null;
  895. }
  896. private bool IsAssignedSourceFolder(SourceFolder sourceFolder)
  897. {
  898. if (m_CachedAssignedSourceFolders.Contains(sourceFolder))
  899. {
  900. return true;
  901. }
  902. if (m_CachedUnassignedSourceFolders.Contains(sourceFolder))
  903. {
  904. return false;
  905. }
  906. foreach (SourceAsset sourceAsset in sourceFolder.GetAssets())
  907. {
  908. if (!IsAssignedSourceAsset(sourceAsset))
  909. {
  910. m_CachedUnassignedSourceFolders.Add(sourceFolder);
  911. return false;
  912. }
  913. }
  914. foreach (SourceFolder subSourceFolder in sourceFolder.GetFolders())
  915. {
  916. if (!IsAssignedSourceFolder(subSourceFolder))
  917. {
  918. m_CachedUnassignedSourceFolders.Add(sourceFolder);
  919. return false;
  920. }
  921. }
  922. m_CachedAssignedSourceFolders.Add(sourceFolder);
  923. return true;
  924. }
  925. private HashSet<SourceAsset> GetSelectedSourceAssets()
  926. {
  927. if (!m_HideAssignedSourceAssets)
  928. {
  929. return m_SelectedSourceAssets;
  930. }
  931. HashSet<SourceAsset> selectedUnassignedSourceAssets = new HashSet<SourceAsset>();
  932. foreach (SourceAsset sourceAsset in m_SelectedSourceAssets)
  933. {
  934. if (!IsAssignedSourceAsset(sourceAsset))
  935. {
  936. selectedUnassignedSourceAssets.Add(sourceAsset);
  937. }
  938. }
  939. return selectedUnassignedSourceAssets;
  940. }
  941. private string GetResourceFullName(string name, string variant)
  942. {
  943. return variant != null ? Utility.Text.Format("{0}.{1}", name, variant) : name;
  944. }
  945. private void OnLoadingResource(int index, int count)
  946. {
  947. EditorUtility.DisplayProgressBar("Loading Resources", Utility.Text.Format("Loading resources, {0}/{1} loaded.", index.ToString(), count.ToString()), (float)index / count);
  948. }
  949. private void OnLoadingAsset(int index, int count)
  950. {
  951. EditorUtility.DisplayProgressBar("Loading Assets", Utility.Text.Format("Loading assets, {0}/{1} loaded.", index.ToString(), count.ToString()), (float)index / count);
  952. }
  953. private void OnLoadCompleted()
  954. {
  955. EditorUtility.ClearProgressBar();
  956. }
  957. private void OnAssetAssigned(SourceAsset[] sourceAssets)
  958. {
  959. HashSet<SourceFolder> affectedFolders = new HashSet<SourceFolder>();
  960. foreach (SourceAsset sourceAsset in sourceAssets)
  961. {
  962. m_CachedAssignedSourceAssets.Add(sourceAsset);
  963. m_CachedUnassignedSourceAssets.Remove(sourceAsset);
  964. affectedFolders.Add(sourceAsset.Folder);
  965. }
  966. foreach (SourceFolder sourceFolder in affectedFolders)
  967. {
  968. SourceFolder folder = sourceFolder;
  969. while (folder != null)
  970. {
  971. m_CachedUnassignedSourceFolders.Remove(folder);
  972. folder = folder.Folder;
  973. }
  974. }
  975. }
  976. private void OnAssetUnassigned(SourceAsset[] sourceAssets)
  977. {
  978. HashSet<SourceFolder> affectedFolders = new HashSet<SourceFolder>();
  979. foreach (SourceAsset sourceAsset in sourceAssets)
  980. {
  981. m_CachedAssignedSourceAssets.Remove(sourceAsset);
  982. m_CachedUnassignedSourceAssets.Add(sourceAsset);
  983. affectedFolders.Add(sourceAsset.Folder);
  984. }
  985. foreach (SourceFolder sourceFolder in affectedFolders)
  986. {
  987. SourceFolder folder = sourceFolder;
  988. while (folder != null)
  989. {
  990. m_CachedSelectedSourceFolders.Remove(folder);
  991. m_CachedAssignedSourceFolders.Remove(folder);
  992. m_CachedUnassignedSourceFolders.Add(folder);
  993. folder = folder.Folder;
  994. }
  995. }
  996. }
  997. }
  998. }