123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using UnityEditor.AddressableAssets.Build;
- using UnityEditor.AddressableAssets.Diagnostics;
- using UnityEditor.AddressableAssets.Settings;
- using UnityEditor.Build.Pipeline.Utilities;
- using UnityEditor.IMGUI.Controls;
- using UnityEngine;
- using UnityEngine.AddressableAssets;
- using UnityEngine.Serialization;
- // ReSharper disable DelegateSubtraction
- namespace UnityEditor.AddressableAssets.GUI
- {
- [Serializable]
- class AddressableAssetsSettingsGroupEditor
- {
- [FormerlySerializedAs("treeState")]
- [SerializeField]
- TreeViewState m_TreeState;
- [FormerlySerializedAs("mchs")]
- [SerializeField]
- MultiColumnHeaderState m_Mchs;
- internal AddressableAssetEntryTreeView m_EntryTree;
- public AddressableAssetsWindow window;
- SearchField m_SearchField;
- const int k_SearchHeight = 20;
- AddressableAssetSettings m_Settings;
- internal AddressableAssetSettings settings
- {
- get
- {
- if (m_Settings == null)
- {
- m_Settings = AddressableAssetSettingsDefaultObject.Settings;
- }
- return m_Settings;
- }
- set => m_Settings = value;
- }
- bool m_ResizingVerticalSplitter;
- Rect m_VerticalSplitterRect = new Rect(0, 0, 10, k_SplitterWidth);
- [SerializeField]
- float m_VerticalSplitterPercent;
- const int k_SplitterWidth = 3;
- public AddressableAssetsSettingsGroupEditor(AddressableAssetsWindow w)
- {
- window = w;
- m_VerticalSplitterPercent = 0.8f;
- OnEnable();
- }
- public void SelectEntries(IList<AddressableAssetEntry> entries)
- {
- List<int> selectedIDs = new List<int>(entries.Count);
- Stack<AssetEntryTreeViewItem> items = new Stack<AssetEntryTreeViewItem>();
-
- if (m_EntryTree == null || m_EntryTree.Root == null)
- InitialiseEntryTree();
-
- foreach (TreeViewItem item in m_EntryTree.Root.children)
- {
- if(item is AssetEntryTreeViewItem i)
- items.Push(i);
- }
- while (items.Count > 0)
- {
- var i = items.Pop();
- bool contains = false;
- if (i.entry != null)
- {
- foreach (AddressableAssetEntry entry in entries)
- {
- // class instances can be different but refer to the same entry, use guid
- if (entry.guid == i.entry.guid && i.entry.TargetAsset == entry.TargetAsset)
- {
- contains = true;
- break;
- }
- }
- }
-
- if (!i.IsGroup && contains)
- {
- selectedIDs.Add(i.id);
- }
- else if (i.hasChildren)
- {
- foreach (TreeViewItem child in i.children)
- {
- if(child is AssetEntryTreeViewItem c)
- items.Push(c);
- }
- }
- }
- foreach (int i in selectedIDs)
- m_EntryTree.FrameItem(i);
- m_EntryTree.SetSelection(selectedIDs);
- }
- void OnSettingsModification(AddressableAssetSettings s, AddressableAssetSettings.ModificationEvent e, object o)
- {
- if (m_EntryTree == null)
- return;
- switch (e)
- {
- case AddressableAssetSettings.ModificationEvent.GroupAdded:
- case AddressableAssetSettings.ModificationEvent.GroupRemoved:
- case AddressableAssetSettings.ModificationEvent.EntryAdded:
- case AddressableAssetSettings.ModificationEvent.EntryMoved:
- case AddressableAssetSettings.ModificationEvent.EntryRemoved:
- case AddressableAssetSettings.ModificationEvent.GroupRenamed:
- case AddressableAssetSettings.ModificationEvent.EntryModified:
- case AddressableAssetSettings.ModificationEvent.BatchModification:
- m_EntryTree.Reload();
- if (window != null)
- window.Repaint();
- break;
- }
- }
- GUIStyle GetStyle(string styleName)
- {
- GUIStyle s = UnityEngine.GUI.skin.FindStyle(styleName);
- if (s == null)
- s = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector).FindStyle(styleName);
- if (s == null)
- {
- Addressables.LogError("Missing built-in guistyle " + styleName);
- s = new GUIStyle();
- }
- return s;
- }
- [NonSerialized]
- List<GUIStyle> m_SearchStyles;
- [NonSerialized]
- GUIStyle m_ButtonStyle;
- [NonSerialized]
- Texture2D m_CogIcon;
- void TopToolbar(Rect toolbarPos)
- {
- if (m_SearchStyles == null)
- {
- m_SearchStyles = new List<GUIStyle>();
- m_SearchStyles.Add(GetStyle("ToolbarSeachTextFieldPopup")); //GetStyle("ToolbarSeachTextField");
- m_SearchStyles.Add(GetStyle("ToolbarSeachCancelButton"));
- m_SearchStyles.Add(GetStyle("ToolbarSeachCancelButtonEmpty"));
- }
- if (m_ButtonStyle == null)
- m_ButtonStyle = GetStyle("ToolbarButton");
- if (m_CogIcon == null)
- m_CogIcon = EditorGUIUtility.FindTexture("_Popup");
- GUILayout.BeginArea(new Rect(0, 0, toolbarPos.width, k_SearchHeight));
- GUILayout.BeginHorizontal(EditorStyles.toolbar);
- {
- float spaceBetween = 4f;
- {
- var guiMode = new GUIContent("Create");
- Rect rMode = GUILayoutUtility.GetRect(guiMode, EditorStyles.toolbarDropDown);
- if (EditorGUI.DropdownButton(rMode, guiMode, FocusType.Passive, EditorStyles.toolbarDropDown))
- {
- var menu = new GenericMenu();
- foreach (var templateObject in settings.GroupTemplateObjects)
- {
- if (templateObject != null)
- menu.AddItem(new GUIContent("Group/" + templateObject.name), false, m_EntryTree.CreateNewGroup, templateObject);
- }
- menu.AddSeparator(string.Empty);
- menu.AddItem(new GUIContent("Group/Blank (no schema)"), false, m_EntryTree.CreateNewGroup, null);
- menu.DropDown(rMode);
- }
- }
- CreateProfileDropdown();
- {
- var guiMode = new GUIContent("Tools");
- Rect rMode = GUILayoutUtility.GetRect(guiMode, EditorStyles.toolbarDropDown);
- if (EditorGUI.DropdownButton(rMode, guiMode, FocusType.Passive, EditorStyles.toolbarDropDown))
- {
- var menu = new GenericMenu();
- menu.AddItem(new GUIContent("Inspect System Settings"), false, () =>
- {
- EditorApplication.ExecuteMenuItem("Window/General/Inspector");
- EditorGUIUtility.PingObject(AddressableAssetSettingsDefaultObject.Settings);
- Selection.activeObject = AddressableAssetSettingsDefaultObject.Settings;
- });
- menu.AddItem(new GUIContent("Check for Content Update Restrictions"), false, OnPrepareUpdate);
-
- menu.AddItem(new GUIContent("Window/Profiles"), false, () => EditorWindow.GetWindow<ProfileWindow>().Show(true));
- menu.AddItem(new GUIContent("Window/Labels"), false, () => EditorWindow.GetWindow<LabelWindow>(true).Intialize(settings));
- menu.AddItem(new GUIContent("Window/Analyze"), false, AnalyzeWindow.ShowWindow);
- menu.AddItem(new GUIContent("Window/Hosting Services"), false, () => EditorWindow.GetWindow<HostingServicesWindow>().Show(settings));
- menu.AddItem(new GUIContent("Window/Event Viewer"), false, ResourceProfilerWindow.ShowWindow);
- menu.AddItem(new GUIContent("Groups View/Show Sprite and Subobject Addresses"), ProjectConfigData.ShowSubObjectsInGroupView, () => { ProjectConfigData.ShowSubObjectsInGroupView = !ProjectConfigData.ShowSubObjectsInGroupView; m_EntryTree.Reload(); });
- menu.AddItem(new GUIContent("Groups View/Group Hierarchy with Dashes", "If enabled, group names are parsed as if a '-' represented a child in hierarchy. So a group called 'a-b-c' would be displayed as if it were in a folder called 'b' that lived in a folder called 'a'. In this mode, only groups without '-' can be rearranged within the groups window."),
- ProjectConfigData.ShowGroupsAsHierarchy, () => { ProjectConfigData.ShowGroupsAsHierarchy = !ProjectConfigData.ShowGroupsAsHierarchy; m_EntryTree.Reload(); });
- var bundleList = AssetDatabase.GetAllAssetBundleNames();
- if (bundleList != null && bundleList.Length > 0)
- menu.AddItem(new GUIContent("Convert Legacy AssetBundles"), false, () => window.OfferToConvert(AddressableAssetSettingsDefaultObject.Settings));
- menu.DropDown(rMode);
- }
- }
- GUILayout.FlexibleSpace();
- GUILayout.Space(spaceBetween * 2f);
- {
- GUILayout.Space(8);
- var guiMode = new GUIContent("Play Mode Script");
- Rect rMode = GUILayoutUtility.GetRect(guiMode, EditorStyles.toolbarDropDown);
- if (EditorGUI.DropdownButton(rMode, guiMode, FocusType.Passive, EditorStyles.toolbarDropDown))
- {
- var menu = new GenericMenu();
- for (int i = 0; i < settings.DataBuilders.Count; i++)
- {
- var m = settings.GetDataBuilder(i);
- if (m.CanBuildData<AddressablesPlayModeBuildResult>())
- menu.AddItem(new GUIContent(m.Name), i == settings.ActivePlayModeDataBuilderIndex, OnSetActivePlayModeScript, i);
- }
- menu.DropDown(rMode);
- }
- }
- var guiBuild = new GUIContent("Build");
- Rect rBuild = GUILayoutUtility.GetRect(guiBuild, EditorStyles.toolbarDropDown);
- if (EditorGUI.DropdownButton(rBuild, guiBuild, FocusType.Passive, EditorStyles.toolbarDropDown))
- {
- //GUIUtility.hotControl = 0;
- var menu = new GenericMenu();
- var AddressablesPlayerBuildResultBuilderExists = false;
- for (int i = 0; i < settings.DataBuilders.Count; i++)
- {
- var m = settings.GetDataBuilder(i);
- if (m.CanBuildData<AddressablesPlayerBuildResult>())
- {
- AddressablesPlayerBuildResultBuilderExists = true;
- menu.AddItem(new GUIContent("New Build/" + m.Name), false, OnBuildScript, i);
- }
- }
- if (!AddressablesPlayerBuildResultBuilderExists)
- {
- menu.AddDisabledItem(new GUIContent("New Build/No Build Script Available"));
- }
- menu.AddItem(new GUIContent("Update a Previous Build"), false, OnUpdateBuild);
- menu.AddItem(new GUIContent("Clean Build/All"), false, OnCleanAll);
- menu.AddItem(new GUIContent("Clean Build/Content Builders/All"), false, OnCleanAddressables, null);
- for (int i = 0; i < settings.DataBuilders.Count; i++)
- {
- var m = settings.GetDataBuilder(i);
- menu.AddItem(new GUIContent("Clean Build/Content Builders/" + m.Name), false, OnCleanAddressables, m);
- }
- menu.AddItem(new GUIContent("Clean Build/Build Pipeline Cache"), false, OnCleanSBP);
- menu.DropDown(rBuild);
- }
- #if (ENABLE_CCD && UNITY_2019_4_OR_NEWER)
- //Build & Release
- var guiBuildAndRelease = new GUIContent("Build & Release");
- if (GUILayout.Button(guiBuildAndRelease, EditorStyles.toolbarButton))
- {
- OnBuildAndRelease();
- }
- #endif
- GUILayout.Space(4);
- Rect searchRect = GUILayoutUtility.GetRect(0, toolbarPos.width * 0.6f, 16f, 16f, m_SearchStyles[0], GUILayout.MinWidth(65), GUILayout.MaxWidth(300));
- Rect popupPosition = searchRect;
- popupPosition.width = 20;
- if (Event.current.type == EventType.MouseDown && popupPosition.Contains(Event.current.mousePosition))
- {
- var menu = new GenericMenu();
- menu.AddItem(new GUIContent("Hierarchical Search"), ProjectConfigData.HierarchicalSearch, OnHierSearchClick);
- menu.DropDown(popupPosition);
- }
- else
- {
- var baseSearch = ProjectConfigData.HierarchicalSearch ? m_EntryTree.customSearchString : m_EntryTree.searchString;
- var searchString = m_SearchField.OnGUI(searchRect, baseSearch, m_SearchStyles[0], m_SearchStyles[1], m_SearchStyles[2]);
- if (baseSearch != searchString)
- {
- m_EntryTree?.Search(searchString);
- }
- }
- }
- GUILayout.EndHorizontal();
- GUILayout.EndArea();
- }
- void OnCleanAll()
- {
- OnCleanAddressables(null);
- OnCleanSBP();
- }
- void OnCleanAddressables(object builder)
- {
- AddressableAssetSettings.CleanPlayerContent(builder as IDataBuilder);
- }
- void OnCleanSBP()
- {
- BuildCache.PurgeCache(true);
- }
- void OnPrepareUpdate()
- {
- var path = ContentUpdateScript.GetContentStateDataPath(true);
- if (string.IsNullOrEmpty(path))
- Debug.LogWarning("No path specified for Content State Data file.");
- else if (!File.Exists(path))
- Debug.LogWarningFormat("No Content State Data file exists at path: {0}");
- else
- ContentUpdatePreviewWindow.PrepareForContentUpdate(AddressableAssetSettingsDefaultObject.Settings, path);
- }
- #if (ENABLE_CCD && UNITY_2019_4_OR_NEWER)
- async void OnBuildAndRelease()
- {
- await AddressableAssetSettings.BuildAndReleasePlayerContent();
- }
- #endif
- void OnBuildScript(object context)
- {
- OnSetActiveBuildScript(context);
- OnBuildPlayerData();
- }
- void OnBuildPlayerData()
- {
- AddressableAssetSettings.BuildPlayerContent();
- }
- void OnUpdateBuild()
- {
- var path = ContentUpdateScript.GetContentStateDataPath(true);
- if (!string.IsNullOrEmpty(path))
- ContentUpdateScript.BuildContentUpdate(AddressableAssetSettingsDefaultObject.Settings, path);
- }
- void OnSetActiveBuildScript(object context)
- {
- AddressableAssetSettingsDefaultObject.Settings.ActivePlayerDataBuilderIndex = (int)context;
- }
- void OnSetActivePlayModeScript(object context)
- {
- AddressableAssetSettingsDefaultObject.Settings.ActivePlayModeDataBuilderIndex = (int)context;
- }
- void OnHierSearchClick()
- {
- ProjectConfigData.HierarchicalSearch = !ProjectConfigData.HierarchicalSearch;
- m_EntryTree.SwapSearchType();
- m_EntryTree.Reload();
- m_EntryTree.Repaint();
- }
- void CreateProfileDropdown()
- {
- var activeProfileName = settings.profileSettings.GetProfileName(settings.activeProfileId);
- if (string.IsNullOrEmpty(activeProfileName))
- {
- settings.activeProfileId = null; //this will reset it to default.
- activeProfileName = settings.profileSettings.GetProfileName(settings.activeProfileId);
- }
- var profileButton = new GUIContent("Profile: " + activeProfileName);
- Rect r = GUILayoutUtility.GetRect(profileButton, m_ButtonStyle, GUILayout.Width(115f));
- if (EditorGUI.DropdownButton(r, profileButton, FocusType.Passive, EditorStyles.toolbarDropDown))
- {
- //GUIUtility.hotControl = 0;
- var menu = new GenericMenu();
- var nameList = settings.profileSettings.GetAllProfileNames();
- foreach (var name in nameList)
- {
- menu.AddItem(new GUIContent(name), name == activeProfileName, SetActiveProfile, name);
- }
- menu.AddSeparator(string.Empty);
- menu.AddItem(new GUIContent("Manage Profiles"), false, () => EditorWindow.GetWindow<ProfileWindow>().Show(true));
- menu.DropDown(r);
- }
- }
- void SetActiveProfile(object context)
- {
- var n = context as string;
- AddressableAssetSettingsDefaultObject.Settings.activeProfileId = AddressableAssetSettingsDefaultObject.Settings.profileSettings.GetProfileId(n);
- AddressableAssetUtility.OpenAssetIfUsingVCIntegration(AddressableAssetSettingsDefaultObject.Settings);
- }
- bool m_ModificationRegistered;
- public void OnEnable()
- {
- if (AddressableAssetSettingsDefaultObject.Settings == null)
- return;
- if (!m_ModificationRegistered)
- {
- AddressableAssetSettingsDefaultObject.Settings.OnModification += OnSettingsModification;
- m_ModificationRegistered = true;
- }
- }
- public void OnDisable()
- {
- if (AddressableAssetSettingsDefaultObject.Settings == null)
- return;
- if (m_ModificationRegistered)
- {
- AddressableAssetSettingsDefaultObject.Settings.OnModification -= OnSettingsModification;
- m_ModificationRegistered = false;
- }
- }
- public bool OnGUI(Rect pos)
- {
- if (settings == null)
- return false;
- if (!m_ModificationRegistered)
- {
- m_ModificationRegistered = true;
- settings.OnModification -= OnSettingsModification; //just in case...
- settings.OnModification += OnSettingsModification;
- }
- if (m_EntryTree == null)
- InitialiseEntryTree();
- HandleVerticalResize(pos);
- var inRectY = pos.height;
- var searchRect = new Rect(pos.xMin, pos.yMin, pos.width, k_SearchHeight);
- var treeRect = new Rect(pos.xMin, pos.yMin + k_SearchHeight, pos.width, inRectY - k_SearchHeight);
- TopToolbar(searchRect);
- m_EntryTree.OnGUI(treeRect);
- return m_ResizingVerticalSplitter;
- }
- internal AddressableAssetEntryTreeView InitialiseEntryTree()
- {
- if (m_TreeState == null)
- m_TreeState = new TreeViewState();
- var headerState = AddressableAssetEntryTreeView.CreateDefaultMultiColumnHeaderState();
- if (MultiColumnHeaderState.CanOverwriteSerializedFields(m_Mchs, headerState))
- MultiColumnHeaderState.OverwriteSerializedFields(m_Mchs, headerState);
- m_Mchs = headerState;
- m_SearchField = new SearchField();
- m_EntryTree = new AddressableAssetEntryTreeView(m_TreeState, m_Mchs, this);
- m_EntryTree.Reload();
- return m_EntryTree;
- }
- public void Reload()
- {
- if (m_EntryTree != null)
- m_EntryTree.Reload();
- }
- void HandleVerticalResize(Rect position)
- {
- m_VerticalSplitterRect.y = (int)(position.yMin + position.height * m_VerticalSplitterPercent);
- m_VerticalSplitterRect.width = position.width;
- m_VerticalSplitterRect.height = k_SplitterWidth;
- EditorGUIUtility.AddCursorRect(m_VerticalSplitterRect, MouseCursor.ResizeVertical);
- if (Event.current.type == EventType.MouseDown && m_VerticalSplitterRect.Contains(Event.current.mousePosition))
- m_ResizingVerticalSplitter = true;
- if (m_ResizingVerticalSplitter)
- {
- var mousePosInRect = Event.current.mousePosition.y - position.yMin;
- m_VerticalSplitterPercent = Mathf.Clamp(mousePosInRect / position.height, 0.20f, 0.90f);
- m_VerticalSplitterRect.y = (int)(position.height * m_VerticalSplitterPercent + position.yMin);
- if (Event.current.type == EventType.MouseUp)
- {
- m_ResizingVerticalSplitter = false;
- }
- }
- else
- m_VerticalSplitterPercent = Mathf.Clamp(m_VerticalSplitterPercent, 0.20f, 0.90f);
- }
- }
- }
|