From 5d63d14a2d31819595a6a25ebf92bb5726f61942 Mon Sep 17 00:00:00 2001 From: Takumi Katsuraya Date: Tue, 4 Oct 2022 12:32:37 +0900 Subject: [PATCH] feat: add multiple AddressableImportSettings support (#77) --- Editor/AddressableImportSettings.cs | 53 ++++++----- Editor/AddressableImportSettingsList.cs | 92 +++++++++++++++++++ Editor/AddressableImportSettingsList.cs.meta | 11 +++ Editor/AddressableImporter.cs | 49 +++++++--- .../Helper/AddressableImportSettingsEditor.cs | 66 +------------ .../AddressableImportSettingsListEditor.cs | 21 +++++ ...ddressableImportSettingsListEditor.cs.meta | 11 +++ Editor/Helper/ScriptableObjectEditor.cs | 85 +++++++++++++++++ Editor/Helper/ScriptableObjectEditor.cs.meta | 11 +++ 9 files changed, 298 insertions(+), 101 deletions(-) create mode 100644 Editor/AddressableImportSettingsList.cs create mode 100644 Editor/AddressableImportSettingsList.cs.meta create mode 100644 Editor/Helper/AddressableImportSettingsListEditor.cs create mode 100644 Editor/Helper/AddressableImportSettingsListEditor.cs.meta create mode 100644 Editor/Helper/ScriptableObjectEditor.cs create mode 100644 Editor/Helper/ScriptableObjectEditor.cs.meta diff --git a/Editor/AddressableImportSettings.cs b/Editor/AddressableImportSettings.cs index fc58a69..10fefe9 100644 --- a/Editor/AddressableImportSettings.cs +++ b/Editor/AddressableImportSettings.cs @@ -3,17 +3,18 @@ using UnityEditor.AddressableAssets; using System.Collections.Generic; using System.Linq; +using System.IO; using UnityAddressableImporter.Helper; #if ODIN_INSPECTOR using Sirenix.OdinInspector; #endif -[CreateAssetMenu(fileName = "AddressableImportSettings", menuName = "Addressables/Import Settings", order = 50)] public class AddressableImportSettings : ScriptableObject { - public const string kConfigObjectName = "addressableimportsettings"; - public const string kDefaultPath = "Assets/AddressableAssetsData/AddressableImportSettings.asset"; + [Tooltip("Toggle rules enabled state")] + [SerializeField] + public bool rulesEnabled = true; [Tooltip("Creates a group if the specified group doesn't exist.")] public bool allowGroupCreation = false; @@ -59,30 +60,34 @@ public void CleanEmptyGroup() } } - public static AddressableImportSettings Instance + /// + /// Create AddressableImportSettings and Add it to AddressableImportSettingsList + /// + [MenuItem("Assets/Create/Addressables/Import Settings", false, 50)] + public static void CreateAsset() { - get + string directoryPath = "Assets/"; + string fileName = "AddressableImportSettings.asset"; + + foreach(var obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets)) { - AddressableImportSettings so; - // Try to locate settings from EditorBuildSettings - if (EditorBuildSettings.TryGetConfigObject(kConfigObjectName, out so)) - return so; - // Try to locate settings from default path - so = AssetDatabase.LoadAssetAtPath(kDefaultPath); - if (so != null) { - EditorBuildSettings.AddConfigObject(kConfigObjectName, so, true); - return so; + var assetPath = AssetDatabase.GetAssetPath(obj); + var assetDirectoryPath = AssetDatabase.IsValidFolder(assetPath) ? assetPath : Path.GetDirectoryName(assetPath); + if (AssetDatabase.IsValidFolder(assetDirectoryPath)) + { + directoryPath = assetDirectoryPath; } - // Try to locate settings from AssetDatabase - var path = AssetDatabase.FindAssets($"t:{nameof(AddressableImportSettings)}"); - if (path.Length > 0) { - var assetPath = AssetDatabase.GUIDToAssetPath(path[0]); - so = AssetDatabase.LoadAssetAtPath(assetPath); - EditorBuildSettings.AddConfigObject(kConfigObjectName, so, true); - return so; - } - return null; } - } + AddressableImportSettings settings = ScriptableObject.CreateInstance(); + var filePath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(directoryPath, fileName)); + AssetDatabase.CreateAsset(settings, filePath); + if (!AddressableImportSettingsList.Instance.SettingList.Contains(settings)) + { + AddressableImportSettingsList.Instance.SettingList.Add(settings); + } + + AssetDatabase.SaveAssets(); + Selection.activeObject = settings; + } } \ No newline at end of file diff --git a/Editor/AddressableImportSettingsList.cs b/Editor/AddressableImportSettingsList.cs new file mode 100644 index 0000000..e829c59 --- /dev/null +++ b/Editor/AddressableImportSettingsList.cs @@ -0,0 +1,92 @@ +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.Linq; +using System.IO; +using UnityAddressableImporter.Helper; + +public class AddressableImportSettingsList : ScriptableObject +{ + public const string kConfigObjectName = "addressableimportsettingslist"; + public const string kDefaultPath = "Assets/AddressableAssetsData/AddressableImportSettingsList.asset"; + public List SettingList; + public List EnabledSettingsList => SettingList.Where((s) => s?.rulesEnabled == true).ToList(); + + public static AddressableImportSettingsList Instance + { + get + { + AddressableImportSettingsList so; + + // Try to locate settings from EditorBuildSettings + if (EditorBuildSettings.TryGetConfigObject(kConfigObjectName, out so)) + { + return so; + } + // Try to locate settings from default path + so = AssetDatabase.LoadAssetAtPath(kDefaultPath); + if (so != null) + { + EditorBuildSettings.AddConfigObject(kConfigObjectName, so, true); + return so; + } + // Try to locate settings from AssetDatabase + var guidList = AssetDatabase.FindAssets($"t:{nameof(AddressableImportSettingsList)}"); + if (guidList.Length > 0) + { + var assetPath = AssetDatabase.GUIDToAssetPath(guidList[0]); + so = AssetDatabase.LoadAssetAtPath(assetPath); + EditorBuildSettings.AddConfigObject(kConfigObjectName, so, true); + return so; + } + + // If AddressableImportSettingsList doesn't exist but AddressableImportSettings exists. create automatically. + var importSettingsGuidList = AssetDatabase.FindAssets($"t:{nameof(AddressableImportSettings)}"); + if (importSettingsGuidList.Length > 0) + { + var settingList = importSettingsGuidList.Select((guid) => AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid))).ToList(); + var asset = ScriptableObject.CreateInstance(); + asset.SettingList = settingList; + var path = Path.Combine(Path.GetDirectoryName(AssetDatabase.GUIDToAssetPath(importSettingsGuidList[0])), + nameof(AddressableImportSettingsList) + ".asset"); + Debug.LogFormat("AddressableImportSettingsList doesn't exist. so it is created automatically. path : {0}", path); + AssetDatabase.CreateAsset(asset, path); + AssetDatabase.SaveAssets(); + so = asset; + EditorBuildSettings.AddConfigObject(kConfigObjectName, so, true); + return so; + } + + return null; + } + } + + public bool RemoveMissingImportSettings() + { + bool removedAnySettings = false; + for (int i = SettingList.Count - 1; i >= 0; --i) + { + if (SettingList[i] == null) + { + SettingList.RemoveAt(i); + removedAnySettings = true; + } + } + + return removedAnySettings; + } + + [ButtonMethod] + public void Reset() + { + var importSettingsGuidList = AssetDatabase.FindAssets($"t:{nameof(AddressableImportSettings)}"); + SettingList = importSettingsGuidList.Select((guid) => AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid))).ToList(); + AssetDatabase.SaveAssets(); + } + + [ButtonMethod] + public void Documentation() + { + Application.OpenURL("https://github.com/favoyang/unity-addressable-importer/blob/master/Documentation~/AddressableImporter.md"); + } +} diff --git a/Editor/AddressableImportSettingsList.cs.meta b/Editor/AddressableImportSettingsList.cs.meta new file mode 100644 index 0000000..70092ba --- /dev/null +++ b/Editor/AddressableImportSettingsList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b98c499e3a0386a42bec431daac600fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/AddressableImporter.cs b/Editor/AddressableImporter.cs index dc047b6..650242d 100644 --- a/Editor/AddressableImporter.cs +++ b/Editor/AddressableImporter.cs @@ -52,14 +52,25 @@ static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAsse } return; } - var importSettings = AddressableImportSettings.Instance; - if (importSettings == null) + var importSettingsList = AddressableImportSettingsList.Instance; + if (importSettingsList == null) { Debug.LogWarningFormat("[AddressableImporter] import settings file not found.\nPlease go to Assets/AddressableAssetsData folder, right click in the project window and choose 'Create > Addressables > Import Settings'."); return; } - if (importSettings.rules == null || importSettings.rules.Count == 0) + + var hasRuleSettingsList = importSettingsList.EnabledSettingsList.Where(s => s.rules.Count > 0).ToList(); + var hasRules = hasRuleSettingsList.Count != 0; + + if (!hasRules) + { + // if AddressableImportSettings is Deleted, Remove missing ImportSettings + if (importSettingsList.RemoveMissingImportSettings()) + { + AssetDatabase.SaveAssets(); + } return; + } // Cache the selection active object var cachedSelectionActiveObject = selectionActiveObject; @@ -85,8 +96,11 @@ static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAsse (float) i / importedAssets.Length)) break; - if (prefabStage == null || prefabAssetPath != importedAsset) // Ignore current editing prefab asset. - dirty |= ApplyImportRule(importedAsset, null, settings, importSettings); + foreach (var importSettings in hasRuleSettingsList) + { + if (prefabStage == null || prefabAssetPath != importedAsset) // Ignore current editing prefab asset. + dirty |= ApplyImportRule(importedAsset, null, settings, importSettings); + } } } finally @@ -100,25 +114,36 @@ static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAsse if (IsAssetIgnored(movedAsset)) continue; var movedFromAssetPath = movedFromAssetPaths[i]; - if (prefabStage == null || prefabAssetPath != movedAsset) // Ignore current editing prefab asset. - dirty |= ApplyImportRule(movedAsset, movedFromAssetPath, settings, importSettings); + + foreach (var importSettings in hasRuleSettingsList) + { + if (prefabStage == null || prefabAssetPath != movedAsset) // Ignore current editing prefab asset. + dirty |= ApplyImportRule(movedAsset, movedFromAssetPath, settings, importSettings); + } } foreach (var deletedAsset in deletedAssets) { if (IsAssetIgnored(deletedAsset)) continue; - if (TryGetMatchedRule(deletedAsset, importSettings, out var matchedRule)) + + foreach (var importSettings in hasRuleSettingsList) { - var guid = AssetDatabase.AssetPathToGUID(deletedAsset); - if (!string.IsNullOrEmpty(guid) && settings.RemoveAssetEntry(guid)) + if (TryGetMatchedRule(deletedAsset, importSettings, out var matchedRule)) { - dirty = true; - Debug.LogFormat("[AddressableImporter] Entry removed for {0}", deletedAsset); + var guid = AssetDatabase.AssetPathToGUID(deletedAsset); + if (!string.IsNullOrEmpty(guid) && settings.RemoveAssetEntry(guid)) + { + dirty = true; + Debug.LogFormat("[AddressableImporter] Entry removed for {0}", deletedAsset); + } } } } + // if AddressableImportSettings is Deleted, Remove missing ImportSettings + dirty |= importSettingsList.RemoveMissingImportSettings(); + if (dirty) { AssetDatabase.SaveAssets(); diff --git a/Editor/Helper/AddressableImportSettingsEditor.cs b/Editor/Helper/AddressableImportSettingsEditor.cs index bd3d3b9..562de2f 100644 --- a/Editor/Helper/AddressableImportSettingsEditor.cs +++ b/Editor/Helper/AddressableImportSettingsEditor.cs @@ -14,72 +14,8 @@ namespace UnityAddressableImporter.Helper.Internal #endif [CustomEditor(typeof(AddressableImportSettings), true), CanEditMultipleObjects] - public class AddressableImportSettingsEditor : Editor + public class AddressableImportSettingsEditor : ScriptableObjectEditor { - private List _methods; - private AddressableImportSettings _target; -#if ODIN_INSPECTOR - private PropertyTree _propertyTree; -#endif - - private void OnEnable() - { - _target = target as AddressableImportSettings; - if (_target == null) return; - -#if ODIN_INSPECTOR - _propertyTree = PropertyTree.Create(_target); -#endif - - _methods = AddressableImporterMethodHandler.CollectValidMembers(_target.GetType()); - } - - public override void OnInspectorGUI() - { - - if (DrawWithOdin() == false) - { - DrawBaseEditor(); - } - - DrawCommands(); - - serializedObject.ApplyModifiedProperties(); - } - - private void DrawBaseEditor() - { - base.OnInspectorGUI(); - } - - private void DrawCommands() - { - if (_methods == null) return; - AddressableImporterMethodHandler.OnInspectorGUI(_target, _methods); - } - - private void OnDisable() - { -#if ODIN_INSPECTOR - _propertyTree?.Dispose(); -#endif - } - - private bool DrawWithOdin() - { - var hasOdinAsset = false; -#if ODIN_INSPECTOR_3 - hasOdinAsset = true; -#endif - if (!hasOdinAsset) return false; - -#if ODIN_INSPECTOR - _propertyTree?.Draw(); - _propertyTree?.ApplyChanges(); -#endif - - return true; - } } } \ No newline at end of file diff --git a/Editor/Helper/AddressableImportSettingsListEditor.cs b/Editor/Helper/AddressableImportSettingsListEditor.cs new file mode 100644 index 0000000..7efeff8 --- /dev/null +++ b/Editor/Helper/AddressableImportSettingsListEditor.cs @@ -0,0 +1,21 @@ +/// +/// ButtonMethodAttribute, +/// modified from https://github.com/Deadcows/MyBox/blob/master/Attributes/ButtonMethodAttribute.cs +/// +namespace UnityAddressableImporter.Helper.Internal +{ + using System.Collections.Generic; + using System.Reflection; + using UnityEditor; + +#if ODIN_INSPECTOR + using Sirenix.OdinInspector; + using Sirenix.OdinInspector.Editor; +#endif + + [CustomEditor(typeof(AddressableImportSettingsList), true), CanEditMultipleObjects] + public class AddressableImportSettingsListEditor : ScriptableObjectEditor + { + + } +} \ No newline at end of file diff --git a/Editor/Helper/AddressableImportSettingsListEditor.cs.meta b/Editor/Helper/AddressableImportSettingsListEditor.cs.meta new file mode 100644 index 0000000..49d9b1e --- /dev/null +++ b/Editor/Helper/AddressableImportSettingsListEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 33b666b485175b04aa46508197f907b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Helper/ScriptableObjectEditor.cs b/Editor/Helper/ScriptableObjectEditor.cs new file mode 100644 index 0000000..0a7faa5 --- /dev/null +++ b/Editor/Helper/ScriptableObjectEditor.cs @@ -0,0 +1,85 @@ +/// +/// ButtonMethodAttribute, +/// modified from https://github.com/Deadcows/MyBox/blob/master/Attributes/ButtonMethodAttribute.cs +/// +namespace UnityAddressableImporter.Helper.Internal +{ + using System.Collections.Generic; + using System.Reflection; + using UnityEditor; + +#if ODIN_INSPECTOR + using Sirenix.OdinInspector; + using Sirenix.OdinInspector.Editor; +#endif + + [CanEditMultipleObjects] + public class ScriptableObjectEditor : Editor + where Type : UnityEngine.Object + { + private List _methods; + private Type _target; + +#if ODIN_INSPECTOR + private PropertyTree _propertyTree; +#endif + + private void OnEnable() + { + _target = target as Type; + if (_target == null) return; + +#if ODIN_INSPECTOR + _propertyTree = PropertyTree.Create(_target); +#endif + _methods = AddressableImporterMethodHandler.CollectValidMembers(_target.GetType()); + } + + public override void OnInspectorGUI() + { + + if (DrawWithOdin() == false) + { + DrawBaseEditor(); + } + + DrawCommands(); + + serializedObject.ApplyModifiedProperties(); + } + + private void DrawBaseEditor() + { + base.OnInspectorGUI(); + } + + private void DrawCommands() + { + if (_methods == null) return; + AddressableImporterMethodHandler.OnInspectorGUI(_target, _methods); + } + + private void OnDisable() + { +#if ODIN_INSPECTOR + _propertyTree?.Dispose(); +#endif + } + + private bool DrawWithOdin() + { + var hasOdinAsset = false; +#if ODIN_INSPECTOR_3 + hasOdinAsset = true; +#endif + if (!hasOdinAsset) return false; + +#if ODIN_INSPECTOR + _propertyTree?.Draw(); + _propertyTree?.ApplyChanges(); +#endif + + return true; + } + } +} \ No newline at end of file diff --git a/Editor/Helper/ScriptableObjectEditor.cs.meta b/Editor/Helper/ScriptableObjectEditor.cs.meta new file mode 100644 index 0000000..87f368e --- /dev/null +++ b/Editor/Helper/ScriptableObjectEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e0dd219dd1bcf344932c1d28f4d706e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: