AssetBundleCollectorWindow.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. #if UNITY_2019_4_OR_NEWER
  2. using System.IO;
  3. using System.Linq;
  4. using System.Collections.Generic;
  5. using UnityEditor;
  6. using UnityEngine;
  7. using UnityEditor.UIElements;
  8. using UnityEngine.UIElements;
  9. namespace YooAsset.Editor
  10. {
  11. public class AssetBundleCollectorWindow : EditorWindow
  12. {
  13. [MenuItem("YooAsset/AssetBundle Collector", false, 101)]
  14. public static void OpenWindow()
  15. {
  16. AssetBundleCollectorWindow window = GetWindow<AssetBundleCollectorWindow>("资源包收集工具", true, WindowsDefine.DockedWindowTypes);
  17. window.minSize = new Vector2(800, 600);
  18. }
  19. private Button _saveButton;
  20. private List<string> _collectorTypeList;
  21. private List<RuleDisplayName> _activeRuleList;
  22. private List<RuleDisplayName> _addressRuleList;
  23. private List<RuleDisplayName> _packRuleList;
  24. private List<RuleDisplayName> _filterRuleList;
  25. private Button _settingsButton;
  26. private VisualElement _helpBoxContainer;
  27. private VisualElement _setting1Container;
  28. private VisualElement _setting2Container;
  29. private Toggle _showPackageToogle;
  30. private Toggle _enableAddressableToogle;
  31. private Toggle _locationToLowerToogle;
  32. private Toggle _includeAssetGUIDToogle;
  33. private Toggle _uniqueBundleNameToogle;
  34. private Toggle _showEditorAliasToggle;
  35. private VisualElement _packageContainer;
  36. private ListView _packageListView;
  37. private TextField _packageNameTxt;
  38. private TextField _packageDescTxt;
  39. private VisualElement _groupContainer;
  40. private ListView _groupListView;
  41. private TextField _groupNameTxt;
  42. private TextField _groupDescTxt;
  43. private TextField _groupAssetTagsTxt;
  44. private VisualElement _collectorContainer;
  45. private ScrollView _collectorScrollView;
  46. private PopupField<RuleDisplayName> _activeRulePopupField;
  47. private int _lastModifyPackageIndex = 0;
  48. private int _lastModifyGroupIndex = 0;
  49. private bool _showSettings = false;
  50. public void CreateGUI()
  51. {
  52. Undo.undoRedoPerformed -= RefreshWindow;
  53. Undo.undoRedoPerformed += RefreshWindow;
  54. try
  55. {
  56. _collectorTypeList = new List<string>()
  57. {
  58. $"{nameof(ECollectorType.MainAssetCollector)}",
  59. $"{nameof(ECollectorType.StaticAssetCollector)}",
  60. $"{nameof(ECollectorType.DependAssetCollector)}"
  61. };
  62. _activeRuleList = AssetBundleCollectorSettingData.GetActiveRuleNames();
  63. _addressRuleList = AssetBundleCollectorSettingData.GetAddressRuleNames();
  64. _packRuleList = AssetBundleCollectorSettingData.GetPackRuleNames();
  65. _filterRuleList = AssetBundleCollectorSettingData.GetFilterRuleNames();
  66. VisualElement root = this.rootVisualElement;
  67. // 加载布局文件
  68. var visualAsset = UxmlLoader.LoadWindowUXML<AssetBundleCollectorWindow>();
  69. if (visualAsset == null)
  70. return;
  71. visualAsset.CloneTree(root);
  72. // 警示栏
  73. _helpBoxContainer = root.Q("HelpBoxContainer");
  74. // 公共设置相关
  75. _settingsButton = root.Q<Button>("SettingsButton");
  76. _settingsButton.clicked += SettingsBtn_clicked;
  77. _setting1Container = root.Q("PublicContainer1");
  78. _setting2Container = root.Q("PublicContainer2");
  79. _showPackageToogle = root.Q<Toggle>("ShowPackages");
  80. _showPackageToogle.RegisterValueChangedCallback(evt =>
  81. {
  82. AssetBundleCollectorSettingData.ModifyPackageView(evt.newValue);
  83. RefreshWindow();
  84. });
  85. _enableAddressableToogle = root.Q<Toggle>("EnableAddressable");
  86. _enableAddressableToogle.RegisterValueChangedCallback(evt =>
  87. {
  88. AssetBundleCollectorSettingData.ModifyAddressable(evt.newValue);
  89. RefreshWindow();
  90. });
  91. _locationToLowerToogle = root.Q<Toggle>("LocationToLower");
  92. _locationToLowerToogle.RegisterValueChangedCallback(evt =>
  93. {
  94. AssetBundleCollectorSettingData.ModifyLocationToLower(evt.newValue);
  95. RefreshWindow();
  96. });
  97. _includeAssetGUIDToogle = root.Q<Toggle>("IncludeAssetGUID");
  98. _includeAssetGUIDToogle.RegisterValueChangedCallback(evt =>
  99. {
  100. AssetBundleCollectorSettingData.ModifyIncludeAssetGUID(evt.newValue);
  101. RefreshWindow();
  102. });
  103. _uniqueBundleNameToogle = root.Q<Toggle>("UniqueBundleName");
  104. _uniqueBundleNameToogle.RegisterValueChangedCallback(evt =>
  105. {
  106. AssetBundleCollectorSettingData.ModifyUniqueBundleName(evt.newValue);
  107. RefreshWindow();
  108. });
  109. _showEditorAliasToggle = root.Q<Toggle>("ShowEditorAlias");
  110. _showEditorAliasToggle.RegisterValueChangedCallback(evt =>
  111. {
  112. AssetBundleCollectorSettingData.ModifyShowEditorAlias(evt.newValue);
  113. RefreshWindow();
  114. });
  115. // 配置修复按钮
  116. var fixBtn = root.Q<Button>("FixButton");
  117. fixBtn.clicked += FixBtn_clicked;
  118. // 导入导出按钮
  119. var exportBtn = root.Q<Button>("ExportButton");
  120. exportBtn.clicked += ExportBtn_clicked;
  121. var importBtn = root.Q<Button>("ImportButton");
  122. importBtn.clicked += ImportBtn_clicked;
  123. // 配置保存按钮
  124. _saveButton = root.Q<Button>("SaveButton");
  125. _saveButton.clicked += SaveBtn_clicked;
  126. // 包裹容器
  127. _packageContainer = root.Q("PackageContainer");
  128. // 包裹列表相关
  129. _packageListView = root.Q<ListView>("PackageListView");
  130. _packageListView.makeItem = MakePackageListViewItem;
  131. _packageListView.bindItem = BindPackageListViewItem;
  132. #if UNITY_2020_1_OR_NEWER
  133. _packageListView.onSelectionChange += PackageListView_onSelectionChange;
  134. #else
  135. _packageListView.onSelectionChanged += PackageListView_onSelectionChange;
  136. #endif
  137. // 包裹添加删除按钮
  138. var packageAddContainer = root.Q("PackageAddContainer");
  139. {
  140. var addBtn = packageAddContainer.Q<Button>("AddBtn");
  141. addBtn.clicked += AddPackageBtn_clicked;
  142. var removeBtn = packageAddContainer.Q<Button>("RemoveBtn");
  143. removeBtn.clicked += RemovePackageBtn_clicked;
  144. }
  145. // 包裹名称
  146. _packageNameTxt = root.Q<TextField>("PackageName");
  147. _packageNameTxt.RegisterValueChangedCallback(evt =>
  148. {
  149. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  150. if (selectPackage != null)
  151. {
  152. selectPackage.PackageName = evt.newValue;
  153. AssetBundleCollectorSettingData.ModifyPackage(selectPackage);
  154. FillPackageViewData();
  155. }
  156. });
  157. // 包裹备注
  158. _packageDescTxt = root.Q<TextField>("PackageDesc");
  159. _packageDescTxt.RegisterValueChangedCallback(evt =>
  160. {
  161. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  162. if (selectPackage != null)
  163. {
  164. selectPackage.PackageDesc = evt.newValue;
  165. AssetBundleCollectorSettingData.ModifyPackage(selectPackage);
  166. FillPackageViewData();
  167. }
  168. });
  169. // 分组列表相关
  170. _groupListView = root.Q<ListView>("GroupListView");
  171. _groupListView.makeItem = MakeGroupListViewItem;
  172. _groupListView.bindItem = BindGroupListViewItem;
  173. #if UNITY_2020_1_OR_NEWER
  174. _groupListView.onSelectionChange += GroupListView_onSelectionChange;
  175. #else
  176. _groupListView.onSelectionChanged += GroupListView_onSelectionChange;
  177. #endif
  178. // 分组添加删除按钮
  179. var groupAddContainer = root.Q("GroupAddContainer");
  180. {
  181. var addBtn = groupAddContainer.Q<Button>("AddBtn");
  182. addBtn.clicked += AddGroupBtn_clicked;
  183. var removeBtn = groupAddContainer.Q<Button>("RemoveBtn");
  184. removeBtn.clicked += RemoveGroupBtn_clicked;
  185. }
  186. // 分组容器
  187. _groupContainer = root.Q("GroupContainer");
  188. // 分组名称
  189. _groupNameTxt = root.Q<TextField>("GroupName");
  190. _groupNameTxt.RegisterValueChangedCallback(evt =>
  191. {
  192. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  193. var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
  194. if (selectPackage != null && selectGroup != null)
  195. {
  196. selectGroup.GroupName = evt.newValue;
  197. AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup);
  198. FillGroupViewData();
  199. }
  200. });
  201. // 分组备注
  202. _groupDescTxt = root.Q<TextField>("GroupDesc");
  203. _groupDescTxt.RegisterValueChangedCallback(evt =>
  204. {
  205. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  206. var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
  207. if (selectPackage != null && selectGroup != null)
  208. {
  209. selectGroup.GroupDesc = evt.newValue;
  210. AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup);
  211. FillGroupViewData();
  212. }
  213. });
  214. // 分组的资源标签
  215. _groupAssetTagsTxt = root.Q<TextField>("GroupAssetTags");
  216. _groupAssetTagsTxt.RegisterValueChangedCallback(evt =>
  217. {
  218. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  219. var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
  220. if (selectPackage != null && selectGroup != null)
  221. {
  222. selectGroup.AssetTags = evt.newValue;
  223. AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup);
  224. }
  225. });
  226. // 收集列表容器
  227. _collectorContainer = root.Q("CollectorContainer");
  228. // 收集列表相关
  229. _collectorScrollView = root.Q<ScrollView>("CollectorScrollView");
  230. _collectorScrollView.style.height = new Length(100, LengthUnit.Percent);
  231. _collectorScrollView.viewDataKey = "scrollView";
  232. // 收集器创建按钮
  233. var collectorAddContainer = root.Q("CollectorAddContainer");
  234. {
  235. var addBtn = collectorAddContainer.Q<Button>("AddBtn");
  236. addBtn.clicked += AddCollectorBtn_clicked;
  237. }
  238. // 分组激活规则
  239. var activeRuleContainer = root.Q("ActiveRuleContainer");
  240. {
  241. _activeRulePopupField = new PopupField<RuleDisplayName>("Active Rule", _activeRuleList, 0);
  242. _activeRulePopupField.name = "ActiveRuleMaskField";
  243. _activeRulePopupField.style.unityTextAlign = TextAnchor.MiddleLeft;
  244. _activeRulePopupField.formatListItemCallback = FormatListItemCallback;
  245. _activeRulePopupField.formatSelectedValueCallback = FormatSelectedValueCallback;
  246. _activeRulePopupField.RegisterValueChangedCallback(evt =>
  247. {
  248. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  249. var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
  250. if (selectPackage != null && selectGroup != null)
  251. {
  252. selectGroup.ActiveRuleName = evt.newValue.ClassName;
  253. AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup);
  254. FillGroupViewData();
  255. }
  256. });
  257. activeRuleContainer.Add(_activeRulePopupField);
  258. }
  259. // 刷新窗体
  260. RefreshWindow();
  261. }
  262. catch (System.Exception e)
  263. {
  264. Debug.LogError(e.ToString());
  265. }
  266. }
  267. public void OnDestroy()
  268. {
  269. // 注意:清空所有撤销操作
  270. Undo.ClearAll();
  271. if (AssetBundleCollectorSettingData.IsDirty)
  272. AssetBundleCollectorSettingData.SaveFile();
  273. }
  274. public void Update()
  275. {
  276. if (_saveButton != null)
  277. {
  278. if (AssetBundleCollectorSettingData.IsDirty)
  279. {
  280. if (_saveButton.enabledSelf == false)
  281. _saveButton.SetEnabled(true);
  282. }
  283. else
  284. {
  285. if (_saveButton.enabledSelf)
  286. _saveButton.SetEnabled(false);
  287. }
  288. }
  289. }
  290. private void RefreshWindow()
  291. {
  292. _showPackageToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowPackageView);
  293. _enableAddressableToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.EnableAddressable);
  294. _locationToLowerToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.LocationToLower);
  295. _includeAssetGUIDToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.IncludeAssetGUID);
  296. _uniqueBundleNameToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.UniqueBundleName);
  297. _showEditorAliasToggle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowEditorAlias);
  298. // 警示框
  299. _helpBoxContainer.Clear();
  300. if (_enableAddressableToogle.value && _locationToLowerToogle.value)
  301. {
  302. var helpBox = new HelpBox("无法同时开启[Enable Addressable]选项和[Location To Lower]选项", HelpBoxMessageType.Error);
  303. _helpBoxContainer.Add(helpBox);
  304. }
  305. if (AssetBundleCollectorSettingData.Setting.Packages.Count > 1 && _uniqueBundleNameToogle.value == false)
  306. {
  307. var helpBox = new HelpBox("检测到当前配置存在多个Package,建议开启[Unique Bundle Name]选项", HelpBoxMessageType.Warning);
  308. _helpBoxContainer.Add(helpBox);
  309. }
  310. if (_helpBoxContainer.childCount > 0)
  311. _helpBoxContainer.style.display = DisplayStyle.Flex;
  312. else
  313. _helpBoxContainer.style.display = DisplayStyle.None;
  314. // 设置栏
  315. if (_showSettings)
  316. {
  317. _setting1Container.style.display = DisplayStyle.Flex;
  318. _setting2Container.style.display = DisplayStyle.Flex;
  319. }
  320. else
  321. {
  322. _setting1Container.style.display = DisplayStyle.None;
  323. _setting2Container.style.display = DisplayStyle.None;
  324. }
  325. _groupContainer.visible = false;
  326. _collectorContainer.visible = false;
  327. FillPackageViewData();
  328. }
  329. private void FixBtn_clicked()
  330. {
  331. AssetBundleCollectorSettingData.FixFile();
  332. RefreshWindow();
  333. }
  334. private void ExportBtn_clicked()
  335. {
  336. string resultPath = EditorTools.OpenFolderPanel("Export XML", "Assets/");
  337. if (resultPath != null)
  338. {
  339. AssetBundleCollectorConfig.ExportXmlConfig($"{resultPath}/{nameof(AssetBundleCollectorConfig)}.xml");
  340. }
  341. }
  342. private void ImportBtn_clicked()
  343. {
  344. string resultPath = EditorTools.OpenFilePath("Import XML", "Assets/", "xml");
  345. if (resultPath != null)
  346. {
  347. AssetBundleCollectorConfig.ImportXmlConfig(resultPath);
  348. RefreshWindow();
  349. }
  350. }
  351. private void SaveBtn_clicked()
  352. {
  353. AssetBundleCollectorSettingData.SaveFile();
  354. }
  355. private void SettingsBtn_clicked()
  356. {
  357. _showSettings = !_showSettings;
  358. RefreshWindow();
  359. }
  360. private string FormatListItemCallback(RuleDisplayName ruleDisplayName)
  361. {
  362. if (_showEditorAliasToggle.value)
  363. return ruleDisplayName.DisplayName;
  364. else
  365. return ruleDisplayName.ClassName;
  366. }
  367. private string FormatSelectedValueCallback(RuleDisplayName ruleDisplayName)
  368. {
  369. if (_showEditorAliasToggle.value)
  370. return ruleDisplayName.DisplayName;
  371. else
  372. return ruleDisplayName.ClassName;
  373. }
  374. // 包裹列表相关
  375. private void FillPackageViewData()
  376. {
  377. _packageListView.Clear();
  378. _packageListView.ClearSelection();
  379. _packageListView.itemsSource = AssetBundleCollectorSettingData.Setting.Packages;
  380. _packageListView.Rebuild();
  381. if (_lastModifyPackageIndex >= 0 && _lastModifyPackageIndex < _packageListView.itemsSource.Count)
  382. {
  383. _packageListView.selectedIndex = _lastModifyPackageIndex;
  384. }
  385. if (_showPackageToogle.value)
  386. _packageContainer.style.display = DisplayStyle.Flex;
  387. else
  388. _packageContainer.style.display = DisplayStyle.None;
  389. }
  390. private VisualElement MakePackageListViewItem()
  391. {
  392. VisualElement element = new VisualElement();
  393. {
  394. var label = new Label();
  395. label.name = "Label1";
  396. label.style.unityTextAlign = TextAnchor.MiddleLeft;
  397. label.style.flexGrow = 1f;
  398. label.style.height = 20f;
  399. element.Add(label);
  400. }
  401. return element;
  402. }
  403. private void BindPackageListViewItem(VisualElement element, int index)
  404. {
  405. var package = AssetBundleCollectorSettingData.Setting.Packages[index];
  406. var textField1 = element.Q<Label>("Label1");
  407. if (string.IsNullOrEmpty(package.PackageDesc))
  408. textField1.text = package.PackageName;
  409. else
  410. textField1.text = $"{package.PackageName} ({package.PackageDesc})";
  411. }
  412. private void PackageListView_onSelectionChange(IEnumerable<object> objs)
  413. {
  414. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  415. if (selectPackage == null)
  416. {
  417. _groupContainer.visible = false;
  418. _collectorContainer.visible = false;
  419. return;
  420. }
  421. _groupContainer.visible = true;
  422. _lastModifyPackageIndex = _packageListView.selectedIndex;
  423. _packageNameTxt.SetValueWithoutNotify(selectPackage.PackageName);
  424. _packageDescTxt.SetValueWithoutNotify(selectPackage.PackageDesc);
  425. FillGroupViewData();
  426. }
  427. private void AddPackageBtn_clicked()
  428. {
  429. Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow AddPackage");
  430. AssetBundleCollectorSettingData.CreatePackage("DefaultPackage");
  431. FillPackageViewData();
  432. }
  433. private void RemovePackageBtn_clicked()
  434. {
  435. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  436. if (selectPackage == null)
  437. return;
  438. Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow RemovePackage");
  439. AssetBundleCollectorSettingData.RemovePackage(selectPackage);
  440. FillPackageViewData();
  441. }
  442. // 分组列表相关
  443. private void FillGroupViewData()
  444. {
  445. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  446. if (selectPackage == null)
  447. return;
  448. _groupListView.Clear();
  449. _groupListView.ClearSelection();
  450. _groupListView.itemsSource = selectPackage.Groups;
  451. _groupListView.Rebuild();
  452. if (_lastModifyGroupIndex >= 0 && _lastModifyGroupIndex < _groupListView.itemsSource.Count)
  453. {
  454. _groupListView.selectedIndex = _lastModifyGroupIndex;
  455. }
  456. }
  457. private VisualElement MakeGroupListViewItem()
  458. {
  459. VisualElement element = new VisualElement();
  460. {
  461. var label = new Label();
  462. label.name = "Label1";
  463. label.style.unityTextAlign = TextAnchor.MiddleLeft;
  464. label.style.flexGrow = 1f;
  465. label.style.height = 20f;
  466. element.Add(label);
  467. }
  468. return element;
  469. }
  470. private void BindGroupListViewItem(VisualElement element, int index)
  471. {
  472. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  473. if (selectPackage == null)
  474. return;
  475. var group = selectPackage.Groups[index];
  476. var textField1 = element.Q<Label>("Label1");
  477. if (string.IsNullOrEmpty(group.GroupDesc))
  478. textField1.text = group.GroupName;
  479. else
  480. textField1.text = $"{group.GroupName} ({group.GroupDesc})";
  481. // 激活状态
  482. IActiveRule activeRule = AssetBundleCollectorSettingData.GetActiveRuleInstance(group.ActiveRuleName);
  483. bool isActive = activeRule.IsActiveGroup();
  484. textField1.SetEnabled(isActive);
  485. }
  486. private void GroupListView_onSelectionChange(IEnumerable<object> objs)
  487. {
  488. var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
  489. if (selectGroup == null)
  490. {
  491. _collectorContainer.visible = false;
  492. return;
  493. }
  494. _collectorContainer.visible = true;
  495. _lastModifyGroupIndex = _groupListView.selectedIndex;
  496. _activeRulePopupField.SetValueWithoutNotify(GetActiveRuleIndex(selectGroup.ActiveRuleName));
  497. _groupNameTxt.SetValueWithoutNotify(selectGroup.GroupName);
  498. _groupDescTxt.SetValueWithoutNotify(selectGroup.GroupDesc);
  499. _groupAssetTagsTxt.SetValueWithoutNotify(selectGroup.AssetTags);
  500. FillCollectorViewData();
  501. }
  502. private void AddGroupBtn_clicked()
  503. {
  504. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  505. if (selectPackage == null)
  506. return;
  507. Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow AddGroup");
  508. AssetBundleCollectorSettingData.CreateGroup(selectPackage, "Default Group");
  509. FillGroupViewData();
  510. }
  511. private void RemoveGroupBtn_clicked()
  512. {
  513. var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
  514. if (selectPackage == null)
  515. return;
  516. var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
  517. if (selectGroup == null)
  518. return;
  519. Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow RemoveGroup");
  520. AssetBundleCollectorSettingData.RemoveGroup(selectPackage, selectGroup);
  521. FillGroupViewData();
  522. }
  523. // 收集列表相关
  524. private void FillCollectorViewData()
  525. {
  526. var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
  527. if (selectGroup == null)
  528. return;
  529. // 填充数据
  530. _collectorScrollView.Clear();
  531. for (int i = 0; i < selectGroup.Collectors.Count; i++)
  532. {
  533. VisualElement element = MakeCollectorListViewItem();
  534. BindCollectorListViewItem(element, i);
  535. _collectorScrollView.Add(element);
  536. }
  537. }
  538. private VisualElement MakeCollectorListViewItem()
  539. {
  540. VisualElement element = new VisualElement();
  541. VisualElement elementTop = new VisualElement();
  542. elementTop.style.flexDirection = FlexDirection.Row;
  543. element.Add(elementTop);
  544. VisualElement elementBottom = new VisualElement();
  545. elementBottom.style.flexDirection = FlexDirection.Row;
  546. element.Add(elementBottom);
  547. VisualElement elementFoldout = new VisualElement();
  548. elementFoldout.style.flexDirection = FlexDirection.Row;
  549. element.Add(elementFoldout);
  550. VisualElement elementSpace = new VisualElement();
  551. elementSpace.style.flexDirection = FlexDirection.Column;
  552. element.Add(elementSpace);
  553. // Top VisualElement
  554. {
  555. var button = new Button();
  556. button.name = "Button1";
  557. button.text = "-";
  558. button.style.unityTextAlign = TextAnchor.MiddleCenter;
  559. button.style.flexGrow = 0f;
  560. elementTop.Add(button);
  561. }
  562. {
  563. var objectField = new ObjectField();
  564. objectField.name = "ObjectField1";
  565. objectField.label = "Collector";
  566. objectField.objectType = typeof(UnityEngine.Object);
  567. objectField.style.unityTextAlign = TextAnchor.MiddleLeft;
  568. objectField.style.flexGrow = 1f;
  569. elementTop.Add(objectField);
  570. var label = objectField.Q<Label>();
  571. label.style.minWidth = 63;
  572. }
  573. // Bottom VisualElement
  574. {
  575. var label = new Label();
  576. label.style.width = 90;
  577. elementBottom.Add(label);
  578. }
  579. {
  580. var popupField = new PopupField<string>(_collectorTypeList, 0);
  581. popupField.name = "PopupField0";
  582. popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
  583. popupField.style.width = 150;
  584. elementBottom.Add(popupField);
  585. }
  586. if (_enableAddressableToogle.value)
  587. {
  588. var popupField = new PopupField<RuleDisplayName>(_addressRuleList, 0);
  589. popupField.name = "PopupField1";
  590. popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
  591. popupField.style.width = 220;
  592. elementBottom.Add(popupField);
  593. }
  594. {
  595. var popupField = new PopupField<RuleDisplayName>(_packRuleList, 0);
  596. popupField.name = "PopupField2";
  597. popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
  598. popupField.style.width = 220;
  599. elementBottom.Add(popupField);
  600. }
  601. {
  602. var popupField = new PopupField<RuleDisplayName>(_filterRuleList, 0);
  603. popupField.name = "PopupField3";
  604. popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
  605. popupField.style.width = 150;
  606. elementBottom.Add(popupField);
  607. }
  608. {
  609. var textField = new TextField();
  610. textField.name = "TextField0";
  611. textField.label = "UserData";
  612. textField.style.width = 200;
  613. elementBottom.Add(textField);
  614. var label = textField.Q<Label>();
  615. label.style.minWidth = 63;
  616. }
  617. {
  618. var textField = new TextField();
  619. textField.name = "TextField1";
  620. textField.label = "Tags";
  621. textField.style.width = 100;
  622. textField.style.marginLeft = 20;
  623. textField.style.flexGrow = 1;
  624. elementBottom.Add(textField);
  625. var label = textField.Q<Label>();
  626. label.style.minWidth = 40;
  627. }
  628. // Foldout VisualElement
  629. {
  630. var label = new Label();
  631. label.style.width = 90;
  632. elementFoldout.Add(label);
  633. }
  634. {
  635. var foldout = new Foldout();
  636. foldout.name = "Foldout1";
  637. foldout.value = false;
  638. foldout.text = "Main Assets";
  639. elementFoldout.Add(foldout);
  640. }
  641. // Space VisualElement
  642. {
  643. var label = new Label();
  644. label.style.height = 10;
  645. elementSpace.Add(label);
  646. }
  647. return element;
  648. }
  649. private void BindCollectorListViewItem(VisualElement element, int index)
  650. {
  651. var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
  652. if (selectGroup == null)
  653. return;
  654. var collector = selectGroup.Collectors[index];
  655. var collectObject = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(collector.CollectPath);
  656. if (collectObject != null)
  657. collectObject.name = collector.CollectPath;
  658. // Foldout
  659. var foldout = element.Q<Foldout>("Foldout1");
  660. foldout.RegisterValueChangedCallback(evt =>
  661. {
  662. if (evt.newValue)
  663. RefreshFoldout(foldout, selectGroup, collector);
  664. else
  665. foldout.Clear();
  666. });
  667. // Remove Button
  668. var removeBtn = element.Q<Button>("Button1");
  669. removeBtn.clicked += () =>
  670. {
  671. RemoveCollectorBtn_clicked(collector);
  672. };
  673. // Collector Path
  674. var objectField1 = element.Q<ObjectField>("ObjectField1");
  675. objectField1.SetValueWithoutNotify(collectObject);
  676. objectField1.RegisterValueChangedCallback(evt =>
  677. {
  678. collector.CollectPath = AssetDatabase.GetAssetPath(evt.newValue);
  679. collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath);
  680. objectField1.value.name = collector.CollectPath;
  681. AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
  682. if (foldout.value)
  683. {
  684. RefreshFoldout(foldout, selectGroup, collector);
  685. }
  686. });
  687. // Collector Type
  688. var popupField0 = element.Q<PopupField<string>>("PopupField0");
  689. popupField0.index = GetCollectorTypeIndex(collector.CollectorType.ToString());
  690. popupField0.RegisterValueChangedCallback(evt =>
  691. {
  692. collector.CollectorType = EditorTools.NameToEnum<ECollectorType>(evt.newValue);
  693. AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
  694. if (foldout.value)
  695. {
  696. RefreshFoldout(foldout, selectGroup, collector);
  697. }
  698. });
  699. // Address Rule
  700. var popupField1 = element.Q<PopupField<RuleDisplayName>>("PopupField1");
  701. if (popupField1 != null)
  702. {
  703. popupField1.index = GetAddressRuleIndex(collector.AddressRuleName);
  704. popupField1.formatListItemCallback = FormatListItemCallback;
  705. popupField1.formatSelectedValueCallback = FormatSelectedValueCallback;
  706. popupField1.RegisterValueChangedCallback(evt =>
  707. {
  708. collector.AddressRuleName = evt.newValue.ClassName;
  709. AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
  710. if (foldout.value)
  711. {
  712. RefreshFoldout(foldout, selectGroup, collector);
  713. }
  714. });
  715. }
  716. // Pack Rule
  717. var popupField2 = element.Q<PopupField<RuleDisplayName>>("PopupField2");
  718. popupField2.index = GetPackRuleIndex(collector.PackRuleName);
  719. popupField2.formatListItemCallback = FormatListItemCallback;
  720. popupField2.formatSelectedValueCallback = FormatSelectedValueCallback;
  721. popupField2.RegisterValueChangedCallback(evt =>
  722. {
  723. collector.PackRuleName = evt.newValue.ClassName;
  724. AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
  725. if (foldout.value)
  726. {
  727. RefreshFoldout(foldout, selectGroup, collector);
  728. }
  729. });
  730. // Filter Rule
  731. var popupField3 = element.Q<PopupField<RuleDisplayName>>("PopupField3");
  732. popupField3.index = GetFilterRuleIndex(collector.FilterRuleName);
  733. popupField3.formatListItemCallback = FormatListItemCallback;
  734. popupField3.formatSelectedValueCallback = FormatSelectedValueCallback;
  735. popupField3.RegisterValueChangedCallback(evt =>
  736. {
  737. collector.FilterRuleName = evt.newValue.ClassName;
  738. AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
  739. if (foldout.value)
  740. {
  741. RefreshFoldout(foldout, selectGroup, collector);
  742. }
  743. });
  744. // UserData
  745. var textFiled0 = element.Q<TextField>("TextField0");
  746. textFiled0.SetValueWithoutNotify(collector.UserData);
  747. textFiled0.RegisterValueChangedCallback(evt =>
  748. {
  749. collector.UserData = evt.newValue;
  750. AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
  751. });
  752. // Tags
  753. var textFiled1 = element.Q<TextField>("TextField1");
  754. textFiled1.SetValueWithoutNotify(collector.AssetTags);
  755. textFiled1.RegisterValueChangedCallback(evt =>
  756. {
  757. collector.AssetTags = evt.newValue;
  758. AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
  759. });
  760. }
  761. private void RefreshFoldout(Foldout foldout, AssetBundleCollectorGroup group, AssetBundleCollector collector)
  762. {
  763. // 清空旧元素
  764. foldout.Clear();
  765. if (collector.IsValid() == false)
  766. {
  767. Debug.LogWarning($"The collector is invalid : {collector.CollectPath} in group : {group.GroupName}");
  768. return;
  769. }
  770. if (collector.CollectorType == ECollectorType.MainAssetCollector || collector.CollectorType == ECollectorType.StaticAssetCollector)
  771. {
  772. List<CollectAssetInfo> collectAssetInfos = null;
  773. try
  774. {
  775. CollectCommand command = new CollectCommand(EBuildMode.SimulateBuild, _packageNameTxt.value,
  776. _enableAddressableToogle.value, _locationToLowerToogle.value, _includeAssetGUIDToogle.value, _uniqueBundleNameToogle.value);
  777. collectAssetInfos = collector.GetAllCollectAssets(command, group);
  778. }
  779. catch (System.Exception e)
  780. {
  781. Debug.LogError(e.ToString());
  782. }
  783. if (collectAssetInfos != null)
  784. {
  785. foreach (var collectAssetInfo in collectAssetInfos)
  786. {
  787. VisualElement elementRow = new VisualElement();
  788. elementRow.style.flexDirection = FlexDirection.Row;
  789. foldout.Add(elementRow);
  790. string showInfo = collectAssetInfo.AssetPath;
  791. if (_enableAddressableToogle.value)
  792. showInfo = $"[{collectAssetInfo.Address}] {collectAssetInfo.AssetPath}";
  793. var label = new Label();
  794. label.text = showInfo;
  795. label.style.width = 300;
  796. label.style.marginLeft = 0;
  797. label.style.flexGrow = 1;
  798. elementRow.Add(label);
  799. }
  800. }
  801. }
  802. }
  803. private void AddCollectorBtn_clicked()
  804. {
  805. var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
  806. if (selectGroup == null)
  807. return;
  808. Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow AddCollector");
  809. AssetBundleCollector collector = new AssetBundleCollector();
  810. AssetBundleCollectorSettingData.CreateCollector(selectGroup, collector);
  811. FillCollectorViewData();
  812. }
  813. private void RemoveCollectorBtn_clicked(AssetBundleCollector selectCollector)
  814. {
  815. var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
  816. if (selectGroup == null)
  817. return;
  818. if (selectCollector == null)
  819. return;
  820. Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow RemoveCollector");
  821. AssetBundleCollectorSettingData.RemoveCollector(selectGroup, selectCollector);
  822. FillCollectorViewData();
  823. }
  824. private int GetCollectorTypeIndex(string typeName)
  825. {
  826. for (int i = 0; i < _collectorTypeList.Count; i++)
  827. {
  828. if (_collectorTypeList[i] == typeName)
  829. return i;
  830. }
  831. return 0;
  832. }
  833. private int GetAddressRuleIndex(string ruleName)
  834. {
  835. for (int i = 0; i < _addressRuleList.Count; i++)
  836. {
  837. if (_addressRuleList[i].ClassName == ruleName)
  838. return i;
  839. }
  840. return 0;
  841. }
  842. private int GetPackRuleIndex(string ruleName)
  843. {
  844. for (int i = 0; i < _packRuleList.Count; i++)
  845. {
  846. if (_packRuleList[i].ClassName == ruleName)
  847. return i;
  848. }
  849. return 0;
  850. }
  851. private int GetFilterRuleIndex(string ruleName)
  852. {
  853. for (int i = 0; i < _filterRuleList.Count; i++)
  854. {
  855. if (_filterRuleList[i].ClassName == ruleName)
  856. return i;
  857. }
  858. return 0;
  859. }
  860. private RuleDisplayName GetActiveRuleIndex(string ruleName)
  861. {
  862. for (int i = 0; i < _activeRuleList.Count; i++)
  863. {
  864. if (_activeRuleList[i].ClassName == ruleName)
  865. return _activeRuleList[i];
  866. }
  867. return _activeRuleList[0];
  868. }
  869. }
  870. }
  871. #endif