123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using UnityEditor.AddressableAssets.Build;
- using UnityEditor.AddressableAssets.Settings;
- using UnityEngine;
- namespace UnityEditor.AddressableAssets.GUI
- {
- using Object = UnityEngine.Object;
- [InitializeOnLoad]
- internal static class AddressableAssetInspectorGUI
- {
- static GUIStyle s_ToggleMixed;
- static GUIContent s_AddressableAssetToggleText;
- static AddressableAssetInspectorGUI()
- {
- s_ToggleMixed = null;
- s_AddressableAssetToggleText = new GUIContent("Addressable", "Check this to mark this asset as an Addressable Asset, which includes it in the bundled data and makes it loadable via script by its address.");
- Editor.finishedDefaultHeaderGUI += OnPostHeaderGUI;
- }
- static void SetAaEntry(AddressableAssetSettings aaSettings, List<TargetInfo> targetInfos, bool create)
- {
- if (create && aaSettings.DefaultGroup.ReadOnly)
- {
- Debug.LogError("Current default group is ReadOnly. Cannot add addressable assets to it");
- return;
- }
- Undo.RecordObject(aaSettings, "AddressableAssetSettings");
- if (!create)
- {
- List<AddressableAssetEntry> removedEntries = new List<AddressableAssetEntry>(targetInfos.Count);
- for (int i = 0; i < targetInfos.Count; ++i)
- {
- AddressableAssetEntry e = aaSettings.FindAssetEntry(targetInfos[i].Guid);
- AddressableAssetUtility.OpenAssetIfUsingVCIntegration(e.parentGroup);
- removedEntries.Add(e);
- aaSettings.RemoveAssetEntry(removedEntries[i], false);
- }
- if (removedEntries.Count > 0)
- aaSettings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryRemoved, removedEntries, true, false);
- }
- else
- {
- AddressableAssetGroup parentGroup = aaSettings.DefaultGroup;
- var resourceTargets = targetInfos.Where(ti => AddressableAssetUtility.IsInResources(ti.Path));
- if (resourceTargets.Any())
- {
- var resourcePaths = resourceTargets.Select(t => t.Path).ToList();
- var resourceGuids = resourceTargets.Select(t => t.Guid).ToList();
- AddressableAssetUtility.SafeMoveResourcesToGroup(aaSettings, parentGroup, resourcePaths, resourceGuids);
- }
-
- var otherTargetInfos = targetInfos.Except(resourceTargets);
- List<string> otherTargetGuids = new List<string>(targetInfos.Count);
- foreach (var info in otherTargetInfos)
- otherTargetGuids.Add(info.Guid);
- var entriesCreated = new List<AddressableAssetEntry>();
- var entriesMoved = new List<AddressableAssetEntry>();
- aaSettings.CreateOrMoveEntries(otherTargetGuids, parentGroup, entriesCreated, entriesMoved, false, false);
-
- bool openedInVC = false;
- if (entriesMoved.Count > 0)
- {
- AddressableAssetUtility.OpenAssetIfUsingVCIntegration(parentGroup);
- openedInVC = true;
- aaSettings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesMoved, true, false);
- }
-
- if (entriesCreated.Count > 0)
- {
- if (!openedInVC)
- AddressableAssetUtility.OpenAssetIfUsingVCIntegration(parentGroup);
- aaSettings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryAdded, entriesCreated, true, false);
- }
- }
- }
- static void OnPostHeaderGUI(Editor editor)
- {
- var aaSettings = AddressableAssetSettingsDefaultObject.Settings;
- if (editor.targets.Length > 0)
- {
- foreach (var t in editor.targets)
- {
- if (t is AddressableAssetGroup || t is AddressableAssetGroupSchema)
- {
- GUILayout.BeginHorizontal();
- GUILayout.Label("Profile: " + AddressableAssetSettingsDefaultObject.GetSettings(true).profileSettings.
- GetProfileName(AddressableAssetSettingsDefaultObject.GetSettings(true).activeProfileId));
- GUILayout.FlexibleSpace();
- if (GUILayout.Button("System Settings", "MiniButton"))
- {
- EditorGUIUtility.PingObject(AddressableAssetSettingsDefaultObject.Settings);
- Selection.activeObject = AddressableAssetSettingsDefaultObject.Settings;
- }
- GUILayout.EndHorizontal();
- return;
- }
- }
-
- List<TargetInfo> targetInfos = GatherTargetInfos(editor.targets, aaSettings);
- if (targetInfos.Count == 0)
- return;
- bool targetHasAddressableSubObject = false;
- int mainAssetsAddressable = 0;
- int subAssetsAddressable = 0;
- foreach (TargetInfo info in targetInfos)
- {
- if (info.MainAssetEntry == null)
- continue;
- if (info.MainAssetEntry.IsSubAsset)
- subAssetsAddressable++;
- else
- mainAssetsAddressable++;
- if (!info.IsMainAsset)
- targetHasAddressableSubObject = true;
- }
-
- // Overrides a DisabledScope in the EditorElement.cs that disables GUI drawn in the header when the asset cannot be edited.
- bool prevEnabledState = UnityEngine.GUI.enabled;
- if (targetHasAddressableSubObject)
- UnityEngine.GUI.enabled = false;
- else
- {
- UnityEngine.GUI.enabled = true;
- foreach (var info in targetInfos)
- {
- if (!info.IsMainAsset)
- {
- UnityEngine.GUI.enabled = false;
- break;
- }
- }
- }
- int totalAddressableCount = mainAssetsAddressable + subAssetsAddressable;
- if (totalAddressableCount == 0) // nothing is addressable
- {
- if (GUILayout.Toggle(false, s_AddressableAssetToggleText, GUILayout.ExpandWidth(false)))
- SetAaEntry(AddressableAssetSettingsDefaultObject.GetSettings(true), targetInfos, true);
- }
- else if (totalAddressableCount == editor.targets.Length) // everything is addressable
- {
- var entryInfo = targetInfos[targetInfos.Count - 1];
- if (entryInfo == null || entryInfo.MainAssetEntry == null)
- throw new NullReferenceException("EntryInfo incorrect for Addressables content.");
-
- GUILayout.BeginHorizontal();
- if (mainAssetsAddressable > 0 && subAssetsAddressable > 0)
- {
- if (s_ToggleMixed == null)
- s_ToggleMixed = new GUIStyle("ToggleMixed");
- if (GUILayout.Toggle(false, s_AddressableAssetToggleText, s_ToggleMixed, GUILayout.ExpandWidth(false)))
- SetAaEntry(aaSettings, targetInfos, true);
- }
- else if (mainAssetsAddressable > 0)
- {
- if (!GUILayout.Toggle(true, s_AddressableAssetToggleText, GUILayout.ExpandWidth(false)))
- {
- SetAaEntry(aaSettings, targetInfos, false);
- UnityEngine.GUI.enabled = prevEnabledState;
- GUIUtility.ExitGUI();
- }
- }
- else if (GUILayout.Toggle(false, s_AddressableAssetToggleText, GUILayout.ExpandWidth(false)))
- SetAaEntry(aaSettings, targetInfos, true);
- if (editor.targets.Length == 1)
- {
- if (!entryInfo.IsMainAsset || entryInfo.MainAssetEntry.IsSubAsset)
- {
- bool preAddressPrevEnabledState = UnityEngine.GUI.enabled;
- UnityEngine.GUI.enabled = false;
- string address = entryInfo.Address + (entryInfo.IsMainAsset ? "" : $"[{entryInfo.TargetObject.name}]");
- EditorGUILayout.DelayedTextField(address, GUILayout.ExpandWidth(true));
- UnityEngine.GUI.enabled = preAddressPrevEnabledState;
- }
- else
- {
- string newAddress = EditorGUILayout.DelayedTextField(entryInfo.Address, GUILayout.ExpandWidth(true));
- if (newAddress != entryInfo.Address)
- {
- if (newAddress.Contains("[") && newAddress.Contains("]"))
- Debug.LogErrorFormat("Rename of address '{0}' cannot contain '[ ]'.", entryInfo.Address);
- else
- {
- entryInfo.MainAssetEntry.address = newAddress;
- AddressableAssetUtility.OpenAssetIfUsingVCIntegration(entryInfo.MainAssetEntry.parentGroup, true);
- }
- }
- }
- }
- else
- {
- FindUniqueAssetGuids(targetInfos, out var uniqueAssetGuids, out var uniqueAddressableAssetGuids);
- EditorGUILayout.LabelField(uniqueAddressableAssetGuids.Count + " out of " + uniqueAssetGuids.Count + " assets are addressable.");
- }
-
- DrawSelectEntriesButton(targetInfos);
- GUILayout.EndHorizontal();
- }
- else // mixed addressable selected
- {
- GUILayout.BeginHorizontal();
- if (s_ToggleMixed == null)
- s_ToggleMixed = new GUIStyle("ToggleMixed");
- if (GUILayout.Toggle(false, s_AddressableAssetToggleText, s_ToggleMixed, GUILayout.ExpandWidth(false)))
- SetAaEntry(AddressableAssetSettingsDefaultObject.GetSettings(true), targetInfos, true);
- FindUniqueAssetGuids(targetInfos, out var uniqueAssetGuids, out var uniqueAddressableAssetGuids);
- EditorGUILayout.LabelField(uniqueAddressableAssetGuids.Count + " out of " + uniqueAssetGuids.Count + " assets are addressable.");
- DrawSelectEntriesButton(targetInfos);
- GUILayout.EndHorizontal();
- }
- UnityEngine.GUI.enabled = prevEnabledState;
- }
- }
- internal static List<TargetInfo> GatherTargetInfos(Object[] targets, AddressableAssetSettings aaSettings)
- {
- var targetInfos = new List<TargetInfo>();
- AddressableAssetEntry entry;
- foreach (var t in targets)
- {
- if (AddressableAssetUtility.TryGetPathAndGUIDFromTarget(t, out var path, out var guid))
- {
- var mainAssetType = AssetDatabase.GetMainAssetTypeAtPath(path);
- // Is asset
- if (mainAssetType != null && !BuildUtility.IsEditorAssembly(mainAssetType.Assembly))
- {
- bool isMainAsset = t is AssetImporter || AssetDatabase.IsMainAsset(t);
- var info = new TargetInfo() {TargetObject = t, Guid = guid, Path = path, IsMainAsset = isMainAsset};
- if (aaSettings != null)
- {
- entry = aaSettings.FindAssetEntry(guid, true);
- if (entry != null)
- info.MainAssetEntry = entry;
- }
- targetInfos.Add(info);
- }
- }
- }
- return targetInfos;
- }
- internal static void FindUniqueAssetGuids(List<TargetInfo> targetInfos, out HashSet<string> uniqueAssetGuids, out HashSet<string> uniqueAddressableAssetGuids)
- {
- uniqueAssetGuids = new HashSet<string>();
- uniqueAddressableAssetGuids = new HashSet<string>();
- foreach (TargetInfo info in targetInfos)
- {
- uniqueAssetGuids.Add(info.Guid);
- if (info.MainAssetEntry != null)
- uniqueAddressableAssetGuids.Add(info.Guid);
- }
- }
- static void DrawSelectEntriesButton(List<TargetInfo> targets)
- {
- var prevGuiEnabled = UnityEngine.GUI.enabled;
- UnityEngine.GUI.enabled = true;
- if (GUILayout.Button("Select"))
- {
- AddressableAssetsWindow.Init();
- var window = EditorWindow.GetWindow<AddressableAssetsWindow>();
- List<AddressableAssetEntry> entries = new List<AddressableAssetEntry>(targets.Count);
- foreach (TargetInfo info in targets)
- {
- if (info.MainAssetEntry != null)
- {
- if (info.IsMainAsset == false && ProjectConfigData.ShowSubObjectsInGroupView)
- {
- List<AddressableAssetEntry> subs = new List<AddressableAssetEntry>();
- info.MainAssetEntry.GatherAllAssets(subs, false, true, true);
- foreach (AddressableAssetEntry sub in subs)
- {
- if (sub.TargetAsset == info.TargetObject)
- {
- entries.Add(sub);
- break;
- }
- }
- }
- else
- entries.Add(info.MainAssetEntry);
- }
- }
- if (entries.Count > 0)
- window.SelectAssetsInGroupEditor(entries);
- }
- UnityEngine.GUI.enabled = prevGuiEnabled;
- }
- internal class TargetInfo
- {
- public UnityEngine.Object TargetObject;
- public string Guid;
- public string Path;
- public bool IsMainAsset;
- public AddressableAssetEntry MainAssetEntry;
- public string Address
- {
- get
- {
- if (MainAssetEntry == null)
- throw new NullReferenceException("No Entry set for Target info with AssetPath " + Path);
- return MainAssetEntry.address;
- }
- }
- }
- }
- }
|