ProjectExporterWindow.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. using System.Collections.Generic;
  2. using AssetBank.DockableWindow.UIHelper;
  3. using UnityEditor;
  4. using UnityEngine;
  5. using UnityEngine.UIElements;
  6. namespace AssetBank.DockableWindow
  7. {
  8. public class ProjectExporterWindow : EditorWindow
  9. {
  10. private ProjectExporterController _controller;
  11. private VisualElement _rootElement;
  12. private VisualElement _contentContainer;
  13. private Dictionary<string, AssetModel> _assetTrees;
  14. private string _currentTab = "General"; // Default to General tab
  15. // Checkbox states for the General tab
  16. private bool _exportScenes = true;
  17. private bool _exportPrefabs = true;
  18. private bool _exportScriptableObjects = true;
  19. private bool _exportMetaFiles = true;
  20. private bool _exportSettings = true;
  21. [MenuItem("Tools/Project Exporter")]
  22. public static void ShowWindow()
  23. {
  24. var wnd = GetWindow<ProjectExporterWindow>();
  25. wnd.titleContent = new GUIContent("Project Exporter", EditorGUIUtility.IconContent("d_Profiler.GlobalIllumination").image);
  26. wnd.minSize = new Vector2(400, 300);
  27. }
  28. private void OnEnable()
  29. {
  30. _controller = new ProjectExporterController();
  31. _assetTrees = new Dictionary<string, AssetModel>();
  32. _rootElement = rootVisualElement;
  33. BuildUI();
  34. RefreshContent(_currentTab);
  35. }
  36. private void BuildUI()
  37. {
  38. _rootElement.Clear();
  39. var tabContainer = new VisualElement { style = { flexDirection = FlexDirection.Row } };
  40. tabContainer.Add(ProjectExporterUI.CreateTab("General")); // New General tab
  41. tabContainer.Add(ProjectExporterUI.CreateTab("Scenes"));
  42. tabContainer.Add(ProjectExporterUI.CreateTab("Prefabs"));
  43. tabContainer.Add(ProjectExporterUI.CreateTab("Scriptable Objects"));
  44. tabContainer.Add(ProjectExporterUI.CreateTab("Meta Files"));
  45. tabContainer.Add(ProjectExporterUI.CreateTab("Settings"));
  46. _rootElement.Add(tabContainer);
  47. var scrollView = new ScrollView(ScrollViewMode.Vertical);
  48. _rootElement.Add(scrollView);
  49. _contentContainer = ProjectExporterUI.CreateMainContainer();
  50. scrollView.Add(_contentContainer);
  51. var generateButton = ProjectExporterUI.CreateGenerateButton(_currentTab == "General");
  52. _rootElement.Add(generateButton);
  53. // The button's action will depend on the current tab
  54. generateButton.clicked += () => {
  55. if (_currentTab == "General")
  56. {
  57. PerformBulkExport();
  58. }
  59. else if (_assetTrees.ContainsKey(_currentTab))
  60. {
  61. _controller.ExportAssets(_assetTrees[_currentTab], _currentTab);
  62. }
  63. };
  64. var tabs = tabContainer.Query<Button>().ToList();
  65. tabs[0].clicked += () => RefreshContent("General");
  66. tabs[1].clicked += () => RefreshContent("Scenes");
  67. tabs[2].clicked += () => RefreshContent("Prefabs");
  68. tabs[3].clicked += () => RefreshContent("Scriptable Objects");
  69. tabs[4].clicked += () => RefreshContent("Meta Files");
  70. tabs[5].clicked += () => RefreshContent("Settings");
  71. }
  72. private void RefreshContent(string tabName)
  73. {
  74. _currentTab = tabName;
  75. _contentContainer.Clear();
  76. if (tabName == "General")
  77. {
  78. DrawGeneralTab();
  79. return;
  80. }
  81. if (!_assetTrees.ContainsKey(tabName))
  82. {
  83. LoadAssetTree(tabName);
  84. }
  85. var rootModel = _assetTrees[tabName];
  86. if (rootModel != null)
  87. {
  88. foreach (var child in rootModel.Children)
  89. {
  90. _contentContainer.Add(CreateAssetView(child, 0));
  91. }
  92. }
  93. }
  94. private void DrawGeneralTab()
  95. {
  96. var title = new Label("Select Export Types") { style = { unityFontStyleAndWeight = FontStyle.Bold } };
  97. _contentContainer.Add(title);
  98. var scenesToggle = ProjectExporterUI.CreateToggle("Export Scenes", _exportScenes, evt => _exportScenes = evt.newValue);
  99. var prefabsToggle = ProjectExporterUI.CreateToggle("Export Prefabs", _exportPrefabs, evt => _exportPrefabs = evt.newValue);
  100. var soToggle = ProjectExporterUI.CreateToggle("Export Scriptable Objects", _exportScriptableObjects, evt => _exportScriptableObjects = evt.newValue);
  101. var metaToggle = ProjectExporterUI.CreateToggle("Export Meta Files", _exportMetaFiles, evt => _exportMetaFiles = evt.newValue);
  102. var settingsToggle = ProjectExporterUI.CreateToggle("Export Settings", _exportSettings, evt => _exportSettings = evt.newValue);
  103. _contentContainer.Add(scenesToggle);
  104. _contentContainer.Add(prefabsToggle);
  105. _contentContainer.Add(soToggle);
  106. _contentContainer.Add(metaToggle);
  107. _contentContainer.Add(settingsToggle);
  108. }
  109. private void PerformBulkExport()
  110. {
  111. if (_exportScenes) ExportAllOfType("Scenes");
  112. if (_exportPrefabs) ExportAllOfType("Prefabs");
  113. if (_exportScriptableObjects) ExportAllOfType("Scriptable Objects");
  114. if (_exportMetaFiles) ExportAllOfType("Meta Files");
  115. if (_exportSettings) ExportAllOfType("Settings");
  116. EditorUtility.DisplayDialog("Bulk Export", "Bulk export process finished.", "OK");
  117. }
  118. private void ExportAllOfType(string type)
  119. {
  120. if (!_assetTrees.ContainsKey(type))
  121. {
  122. LoadAssetTree(type);
  123. }
  124. var rootModel = _assetTrees[type];
  125. if (rootModel != null)
  126. {
  127. SetChildrenSelection(rootModel, true); // Select all assets
  128. _controller.ExportAssets(rootModel, type);
  129. }
  130. }
  131. private void LoadAssetTree(string tabName)
  132. {
  133. EditorUtility.DisplayProgressBar("Loading...", $"Fetching {tabName}...", 0.5f);
  134. try
  135. {
  136. switch (tabName)
  137. {
  138. case "Scenes":
  139. _assetTrees[tabName] = _controller.GetAssets("t:Scene");
  140. break;
  141. case "Prefabs":
  142. _assetTrees[tabName] = _controller.GetAssets("t:Prefab");
  143. break;
  144. case "Scriptable Objects":
  145. _assetTrees[tabName] = _controller.GetAssets("t:ScriptableObject");
  146. break;
  147. case "Meta Files":
  148. _assetTrees[tabName] = _controller.GetAllMetaFiles();
  149. break;
  150. case "Settings":
  151. _assetTrees[tabName] = _controller.GetProjectSettingsFiles();
  152. break;
  153. }
  154. }
  155. finally
  156. {
  157. EditorUtility.ClearProgressBar();
  158. }
  159. }
  160. private VisualElement CreateAssetView(AssetModel model, int indentLevel)
  161. {
  162. const int indentWidth = 20;
  163. if (model.Children.Count > 0)
  164. {
  165. var row = new VisualElement { style = { flexDirection = FlexDirection.Row, alignItems = Align.Center, marginLeft = indentLevel * indentWidth } };
  166. var foldout = ProjectExporterUI.CreateFoldout(model.Name);
  167. foldout.style.flexGrow = 1;
  168. var toggle = new Toggle { value = model.IsSelected, text = "" };
  169. toggle.RegisterValueChangedCallback(evt => {
  170. model.IsSelected = evt.newValue;
  171. SetChildrenSelection(model, evt.newValue);
  172. UpdateChildTogglesUI(foldout, evt.newValue);
  173. });
  174. row.Add(toggle);
  175. row.Add(foldout);
  176. foreach (var child in model.Children)
  177. {
  178. foldout.Add(CreateAssetView(child, indentLevel + 1));
  179. }
  180. return row;
  181. }
  182. else
  183. {
  184. var toggle = ProjectExporterUI.CreateToggle(model.Name);
  185. toggle.style.marginLeft = (indentLevel + 1) * indentWidth;
  186. toggle.value = model.IsSelected;
  187. toggle.RegisterValueChangedCallback(evt => model.IsSelected = evt.newValue);
  188. return toggle;
  189. }
  190. }
  191. private void UpdateChildTogglesUI(VisualElement container, bool isSelected)
  192. {
  193. container.Query<Toggle>().ForEach(childToggle => {
  194. childToggle.SetValueWithoutNotify(isSelected);
  195. });
  196. }
  197. private void SetChildrenSelection(AssetModel parent, bool isSelected)
  198. {
  199. parent.IsSelected = isSelected;
  200. foreach (var child in parent.Children)
  201. {
  202. SetChildrenSelection(child, isSelected);
  203. }
  204. }
  205. }
  206. }