From 791b96f046c32303abe341ead42dc485bce5a951 Mon Sep 17 00:00:00 2001 From: Bruno Mikoski Date: Tue, 8 Aug 2023 14:25:40 +0100 Subject: [PATCH 1/4] fix: folder organization --- Scripts/Editor/Core/Utility.meta | 3 --- Scripts/Editor/{Core => }/CustomEditors.meta | 0 .../CustomEditors/CollectionCustomEditor.cs | 0 .../CollectionCustomEditor.cs.meta | 0 .../CollectionRegistryCustomEditor.cs | 0 .../CollectionRegistryCustomEditor.cs.meta | 0 Scripts/Editor/{Core => }/EditorWindows.meta | 0 .../CreateCollectionWizard.cs | 0 .../CreateCollectionWizard.cs.meta | 0 .../CreateNewCollectionItemFromBaseWizard.cs | 0 ...ateNewCollectionItemFromBaseWizard.cs.meta | 0 .../DeleteCollectionEditorWindow.cs | 0 .../DeleteCollectionEditorWindow.cs.meta | 0 Scripts/Editor/{Core => }/Processors.meta | 0 .../CollectionAssetsModificationProcessor.cs | 0 ...lectionAssetsModificationProcessor.cs.meta | 0 .../Processors/CollectionPreprocessBuild.cs | 0 .../CollectionPreprocessBuild.cs.meta | 0 .../CollectionsAssetsPostProcessor.cs | 0 .../CollectionsAssetsPostProcessor.cs.meta | 0 .../Editor/{Core => }/PropertyDrawers.meta | 0 ...tionItemIndirectReferencePropertyDrawer.cs | 0 ...temIndirectReferencePropertyDrawer.cs.meta | 0 .../CollectionItemPickerPropertyDrawer.cs | 0 ...CollectionItemPickerPropertyDrawer.cs.meta | 0 .../DrawAsSOCItemAttributePropertyDrawer.cs | 0 ...awAsSOCItemAttributePropertyDrawer.cs.meta | 0 .../PropertyDrawers/SOCItemPropertyDrawer.cs | 0 .../SOCItemPropertyDrawer.cs.meta | 0 .../ULongGuidPropertyDrawer.cs | 0 .../ULongGuidPropertyDrawer.cs.meta | 0 .../CopyCollectionItemUtility.cs | 0 .../CopyCollectionItemUtility.cs.meta | 0 .../ScriptableObjectCollectionUtility.cs | 0 .../ScriptableObjectCollectionUtility.cs.meta | 0 .../Wizzard.meta => Runtime/Attributes.meta} | 2 +- .../SOCItemEditorOptionsAttribute.cs | 13 ++++++++- .../SOCItemEditorOptionsAttribute.cs.meta | 0 .../Core/CollectionItemIndirectReference.cs | 2 -- .../Core/{Picker => }/CollectionItemPicker.cs | 0 .../{Picker => }/CollectionItemPicker.cs.meta | 0 .../Runtime/Core/DrawAsSOCItemAttribute.cs | 14 ---------- .../Core/DrawAsSOCItemAttribute.cs.meta | 3 --- Scripts/Runtime/Core/GUID.meta | 3 --- Scripts/Runtime/Core/InitializeCollections.cs | 27 ------------------- .../Core/InitializeCollections.cs.meta | 3 --- Scripts/Runtime/Core/{GUID => }/LongGuid.cs | 0 .../Runtime/Core/{GUID => }/LongGuid.cs.meta | 0 Scripts/Runtime/Core/Picker.meta | 3 --- 49 files changed, 13 insertions(+), 60 deletions(-) delete mode 100644 Scripts/Editor/Core/Utility.meta rename Scripts/Editor/{Core => }/CustomEditors.meta (100%) rename Scripts/Editor/{Core => }/CustomEditors/CollectionCustomEditor.cs (100%) rename Scripts/Editor/{Core => }/CustomEditors/CollectionCustomEditor.cs.meta (100%) rename Scripts/Editor/{Core => }/CustomEditors/CollectionRegistryCustomEditor.cs (100%) rename Scripts/Editor/{Core => }/CustomEditors/CollectionRegistryCustomEditor.cs.meta (100%) rename Scripts/Editor/{Core => }/EditorWindows.meta (100%) rename Scripts/Editor/{Core/Wizzard => EditorWindows}/CreateCollectionWizard.cs (100%) rename Scripts/Editor/{Core/Wizzard => EditorWindows}/CreateCollectionWizard.cs.meta (100%) rename Scripts/Editor/{Core/Wizzard => EditorWindows}/CreateNewCollectionItemFromBaseWizard.cs (100%) rename Scripts/Editor/{Core/Wizzard => EditorWindows}/CreateNewCollectionItemFromBaseWizard.cs.meta (100%) rename Scripts/Editor/{Core => }/EditorWindows/DeleteCollectionEditorWindow.cs (100%) rename Scripts/Editor/{Core => }/EditorWindows/DeleteCollectionEditorWindow.cs.meta (100%) rename Scripts/Editor/{Core => }/Processors.meta (100%) rename Scripts/Editor/{Core => }/Processors/CollectionAssetsModificationProcessor.cs (100%) rename Scripts/Editor/{Core => }/Processors/CollectionAssetsModificationProcessor.cs.meta (100%) rename Scripts/Editor/{Core => }/Processors/CollectionPreprocessBuild.cs (100%) rename Scripts/Editor/{Core => }/Processors/CollectionPreprocessBuild.cs.meta (100%) rename Scripts/Editor/{Core => }/Processors/CollectionsAssetsPostProcessor.cs (100%) rename Scripts/Editor/{Core => }/Processors/CollectionsAssetsPostProcessor.cs.meta (100%) rename Scripts/Editor/{Core => }/PropertyDrawers.meta (100%) rename Scripts/Editor/{Core => }/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs (100%) rename Scripts/Editor/{Core => }/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs.meta (100%) rename Scripts/Editor/{Core => }/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs (100%) rename Scripts/Editor/{Core => }/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs.meta (100%) rename Scripts/Editor/{Core => }/PropertyDrawers/DrawAsSOCItemAttributePropertyDrawer.cs (100%) rename Scripts/Editor/{Core => }/PropertyDrawers/DrawAsSOCItemAttributePropertyDrawer.cs.meta (100%) rename Scripts/Editor/{Core => }/PropertyDrawers/SOCItemPropertyDrawer.cs (100%) rename Scripts/Editor/{Core => }/PropertyDrawers/SOCItemPropertyDrawer.cs.meta (100%) rename Scripts/Editor/{Core => }/PropertyDrawers/ULongGuidPropertyDrawer.cs (100%) rename Scripts/Editor/{Core => }/PropertyDrawers/ULongGuidPropertyDrawer.cs.meta (100%) rename Scripts/Editor/{Core/Utility => Utils}/CopyCollectionItemUtility.cs (100%) rename Scripts/Editor/{Core/Utility => Utils}/CopyCollectionItemUtility.cs.meta (100%) rename Scripts/Editor/{Core/Utility => Utils}/ScriptableObjectCollectionUtility.cs (100%) rename Scripts/Editor/{Core/Utility => Utils}/ScriptableObjectCollectionUtility.cs.meta (100%) rename Scripts/{Editor/Core/Wizzard.meta => Runtime/Attributes.meta} (77%) rename Scripts/Runtime/{Core => Attributes}/SOCItemEditorOptionsAttribute.cs (71%) rename Scripts/Runtime/{Core => Attributes}/SOCItemEditorOptionsAttribute.cs.meta (100%) rename Scripts/Runtime/Core/{Picker => }/CollectionItemPicker.cs (100%) rename Scripts/Runtime/Core/{Picker => }/CollectionItemPicker.cs.meta (100%) delete mode 100644 Scripts/Runtime/Core/DrawAsSOCItemAttribute.cs delete mode 100644 Scripts/Runtime/Core/DrawAsSOCItemAttribute.cs.meta delete mode 100644 Scripts/Runtime/Core/GUID.meta delete mode 100644 Scripts/Runtime/Core/InitializeCollections.cs delete mode 100644 Scripts/Runtime/Core/InitializeCollections.cs.meta rename Scripts/Runtime/Core/{GUID => }/LongGuid.cs (100%) rename Scripts/Runtime/Core/{GUID => }/LongGuid.cs.meta (100%) delete mode 100644 Scripts/Runtime/Core/Picker.meta diff --git a/Scripts/Editor/Core/Utility.meta b/Scripts/Editor/Core/Utility.meta deleted file mode 100644 index 814510c..0000000 --- a/Scripts/Editor/Core/Utility.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2ba1ede35ca94c2d8395a4f824681be7 -timeCreated: 1680616480 \ No newline at end of file diff --git a/Scripts/Editor/Core/CustomEditors.meta b/Scripts/Editor/CustomEditors.meta similarity index 100% rename from Scripts/Editor/Core/CustomEditors.meta rename to Scripts/Editor/CustomEditors.meta diff --git a/Scripts/Editor/Core/CustomEditors/CollectionCustomEditor.cs b/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs similarity index 100% rename from Scripts/Editor/Core/CustomEditors/CollectionCustomEditor.cs rename to Scripts/Editor/CustomEditors/CollectionCustomEditor.cs diff --git a/Scripts/Editor/Core/CustomEditors/CollectionCustomEditor.cs.meta b/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs.meta similarity index 100% rename from Scripts/Editor/Core/CustomEditors/CollectionCustomEditor.cs.meta rename to Scripts/Editor/CustomEditors/CollectionCustomEditor.cs.meta diff --git a/Scripts/Editor/Core/CustomEditors/CollectionRegistryCustomEditor.cs b/Scripts/Editor/CustomEditors/CollectionRegistryCustomEditor.cs similarity index 100% rename from Scripts/Editor/Core/CustomEditors/CollectionRegistryCustomEditor.cs rename to Scripts/Editor/CustomEditors/CollectionRegistryCustomEditor.cs diff --git a/Scripts/Editor/Core/CustomEditors/CollectionRegistryCustomEditor.cs.meta b/Scripts/Editor/CustomEditors/CollectionRegistryCustomEditor.cs.meta similarity index 100% rename from Scripts/Editor/Core/CustomEditors/CollectionRegistryCustomEditor.cs.meta rename to Scripts/Editor/CustomEditors/CollectionRegistryCustomEditor.cs.meta diff --git a/Scripts/Editor/Core/EditorWindows.meta b/Scripts/Editor/EditorWindows.meta similarity index 100% rename from Scripts/Editor/Core/EditorWindows.meta rename to Scripts/Editor/EditorWindows.meta diff --git a/Scripts/Editor/Core/Wizzard/CreateCollectionWizard.cs b/Scripts/Editor/EditorWindows/CreateCollectionWizard.cs similarity index 100% rename from Scripts/Editor/Core/Wizzard/CreateCollectionWizard.cs rename to Scripts/Editor/EditorWindows/CreateCollectionWizard.cs diff --git a/Scripts/Editor/Core/Wizzard/CreateCollectionWizard.cs.meta b/Scripts/Editor/EditorWindows/CreateCollectionWizard.cs.meta similarity index 100% rename from Scripts/Editor/Core/Wizzard/CreateCollectionWizard.cs.meta rename to Scripts/Editor/EditorWindows/CreateCollectionWizard.cs.meta diff --git a/Scripts/Editor/Core/Wizzard/CreateNewCollectionItemFromBaseWizard.cs b/Scripts/Editor/EditorWindows/CreateNewCollectionItemFromBaseWizard.cs similarity index 100% rename from Scripts/Editor/Core/Wizzard/CreateNewCollectionItemFromBaseWizard.cs rename to Scripts/Editor/EditorWindows/CreateNewCollectionItemFromBaseWizard.cs diff --git a/Scripts/Editor/Core/Wizzard/CreateNewCollectionItemFromBaseWizard.cs.meta b/Scripts/Editor/EditorWindows/CreateNewCollectionItemFromBaseWizard.cs.meta similarity index 100% rename from Scripts/Editor/Core/Wizzard/CreateNewCollectionItemFromBaseWizard.cs.meta rename to Scripts/Editor/EditorWindows/CreateNewCollectionItemFromBaseWizard.cs.meta diff --git a/Scripts/Editor/Core/EditorWindows/DeleteCollectionEditorWindow.cs b/Scripts/Editor/EditorWindows/DeleteCollectionEditorWindow.cs similarity index 100% rename from Scripts/Editor/Core/EditorWindows/DeleteCollectionEditorWindow.cs rename to Scripts/Editor/EditorWindows/DeleteCollectionEditorWindow.cs diff --git a/Scripts/Editor/Core/EditorWindows/DeleteCollectionEditorWindow.cs.meta b/Scripts/Editor/EditorWindows/DeleteCollectionEditorWindow.cs.meta similarity index 100% rename from Scripts/Editor/Core/EditorWindows/DeleteCollectionEditorWindow.cs.meta rename to Scripts/Editor/EditorWindows/DeleteCollectionEditorWindow.cs.meta diff --git a/Scripts/Editor/Core/Processors.meta b/Scripts/Editor/Processors.meta similarity index 100% rename from Scripts/Editor/Core/Processors.meta rename to Scripts/Editor/Processors.meta diff --git a/Scripts/Editor/Core/Processors/CollectionAssetsModificationProcessor.cs b/Scripts/Editor/Processors/CollectionAssetsModificationProcessor.cs similarity index 100% rename from Scripts/Editor/Core/Processors/CollectionAssetsModificationProcessor.cs rename to Scripts/Editor/Processors/CollectionAssetsModificationProcessor.cs diff --git a/Scripts/Editor/Core/Processors/CollectionAssetsModificationProcessor.cs.meta b/Scripts/Editor/Processors/CollectionAssetsModificationProcessor.cs.meta similarity index 100% rename from Scripts/Editor/Core/Processors/CollectionAssetsModificationProcessor.cs.meta rename to Scripts/Editor/Processors/CollectionAssetsModificationProcessor.cs.meta diff --git a/Scripts/Editor/Core/Processors/CollectionPreprocessBuild.cs b/Scripts/Editor/Processors/CollectionPreprocessBuild.cs similarity index 100% rename from Scripts/Editor/Core/Processors/CollectionPreprocessBuild.cs rename to Scripts/Editor/Processors/CollectionPreprocessBuild.cs diff --git a/Scripts/Editor/Core/Processors/CollectionPreprocessBuild.cs.meta b/Scripts/Editor/Processors/CollectionPreprocessBuild.cs.meta similarity index 100% rename from Scripts/Editor/Core/Processors/CollectionPreprocessBuild.cs.meta rename to Scripts/Editor/Processors/CollectionPreprocessBuild.cs.meta diff --git a/Scripts/Editor/Core/Processors/CollectionsAssetsPostProcessor.cs b/Scripts/Editor/Processors/CollectionsAssetsPostProcessor.cs similarity index 100% rename from Scripts/Editor/Core/Processors/CollectionsAssetsPostProcessor.cs rename to Scripts/Editor/Processors/CollectionsAssetsPostProcessor.cs diff --git a/Scripts/Editor/Core/Processors/CollectionsAssetsPostProcessor.cs.meta b/Scripts/Editor/Processors/CollectionsAssetsPostProcessor.cs.meta similarity index 100% rename from Scripts/Editor/Core/Processors/CollectionsAssetsPostProcessor.cs.meta rename to Scripts/Editor/Processors/CollectionsAssetsPostProcessor.cs.meta diff --git a/Scripts/Editor/Core/PropertyDrawers.meta b/Scripts/Editor/PropertyDrawers.meta similarity index 100% rename from Scripts/Editor/Core/PropertyDrawers.meta rename to Scripts/Editor/PropertyDrawers.meta diff --git a/Scripts/Editor/Core/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs b/Scripts/Editor/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs similarity index 100% rename from Scripts/Editor/Core/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs rename to Scripts/Editor/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs diff --git a/Scripts/Editor/Core/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs.meta b/Scripts/Editor/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs.meta similarity index 100% rename from Scripts/Editor/Core/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs.meta rename to Scripts/Editor/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs.meta diff --git a/Scripts/Editor/Core/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs b/Scripts/Editor/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs similarity index 100% rename from Scripts/Editor/Core/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs rename to Scripts/Editor/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs diff --git a/Scripts/Editor/Core/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs.meta b/Scripts/Editor/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs.meta similarity index 100% rename from Scripts/Editor/Core/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs.meta rename to Scripts/Editor/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs.meta diff --git a/Scripts/Editor/Core/PropertyDrawers/DrawAsSOCItemAttributePropertyDrawer.cs b/Scripts/Editor/PropertyDrawers/DrawAsSOCItemAttributePropertyDrawer.cs similarity index 100% rename from Scripts/Editor/Core/PropertyDrawers/DrawAsSOCItemAttributePropertyDrawer.cs rename to Scripts/Editor/PropertyDrawers/DrawAsSOCItemAttributePropertyDrawer.cs diff --git a/Scripts/Editor/Core/PropertyDrawers/DrawAsSOCItemAttributePropertyDrawer.cs.meta b/Scripts/Editor/PropertyDrawers/DrawAsSOCItemAttributePropertyDrawer.cs.meta similarity index 100% rename from Scripts/Editor/Core/PropertyDrawers/DrawAsSOCItemAttributePropertyDrawer.cs.meta rename to Scripts/Editor/PropertyDrawers/DrawAsSOCItemAttributePropertyDrawer.cs.meta diff --git a/Scripts/Editor/Core/PropertyDrawers/SOCItemPropertyDrawer.cs b/Scripts/Editor/PropertyDrawers/SOCItemPropertyDrawer.cs similarity index 100% rename from Scripts/Editor/Core/PropertyDrawers/SOCItemPropertyDrawer.cs rename to Scripts/Editor/PropertyDrawers/SOCItemPropertyDrawer.cs diff --git a/Scripts/Editor/Core/PropertyDrawers/SOCItemPropertyDrawer.cs.meta b/Scripts/Editor/PropertyDrawers/SOCItemPropertyDrawer.cs.meta similarity index 100% rename from Scripts/Editor/Core/PropertyDrawers/SOCItemPropertyDrawer.cs.meta rename to Scripts/Editor/PropertyDrawers/SOCItemPropertyDrawer.cs.meta diff --git a/Scripts/Editor/Core/PropertyDrawers/ULongGuidPropertyDrawer.cs b/Scripts/Editor/PropertyDrawers/ULongGuidPropertyDrawer.cs similarity index 100% rename from Scripts/Editor/Core/PropertyDrawers/ULongGuidPropertyDrawer.cs rename to Scripts/Editor/PropertyDrawers/ULongGuidPropertyDrawer.cs diff --git a/Scripts/Editor/Core/PropertyDrawers/ULongGuidPropertyDrawer.cs.meta b/Scripts/Editor/PropertyDrawers/ULongGuidPropertyDrawer.cs.meta similarity index 100% rename from Scripts/Editor/Core/PropertyDrawers/ULongGuidPropertyDrawer.cs.meta rename to Scripts/Editor/PropertyDrawers/ULongGuidPropertyDrawer.cs.meta diff --git a/Scripts/Editor/Core/Utility/CopyCollectionItemUtility.cs b/Scripts/Editor/Utils/CopyCollectionItemUtility.cs similarity index 100% rename from Scripts/Editor/Core/Utility/CopyCollectionItemUtility.cs rename to Scripts/Editor/Utils/CopyCollectionItemUtility.cs diff --git a/Scripts/Editor/Core/Utility/CopyCollectionItemUtility.cs.meta b/Scripts/Editor/Utils/CopyCollectionItemUtility.cs.meta similarity index 100% rename from Scripts/Editor/Core/Utility/CopyCollectionItemUtility.cs.meta rename to Scripts/Editor/Utils/CopyCollectionItemUtility.cs.meta diff --git a/Scripts/Editor/Core/Utility/ScriptableObjectCollectionUtility.cs b/Scripts/Editor/Utils/ScriptableObjectCollectionUtility.cs similarity index 100% rename from Scripts/Editor/Core/Utility/ScriptableObjectCollectionUtility.cs rename to Scripts/Editor/Utils/ScriptableObjectCollectionUtility.cs diff --git a/Scripts/Editor/Core/Utility/ScriptableObjectCollectionUtility.cs.meta b/Scripts/Editor/Utils/ScriptableObjectCollectionUtility.cs.meta similarity index 100% rename from Scripts/Editor/Core/Utility/ScriptableObjectCollectionUtility.cs.meta rename to Scripts/Editor/Utils/ScriptableObjectCollectionUtility.cs.meta diff --git a/Scripts/Editor/Core/Wizzard.meta b/Scripts/Runtime/Attributes.meta similarity index 77% rename from Scripts/Editor/Core/Wizzard.meta rename to Scripts/Runtime/Attributes.meta index 2ba5fd5..1ef5f1a 100644 --- a/Scripts/Editor/Core/Wizzard.meta +++ b/Scripts/Runtime/Attributes.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e1d20e0e0c4955a46938914ffc60b24f +guid: 277a2d24831ef0949b9792691645e9c7 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Scripts/Runtime/Core/SOCItemEditorOptionsAttribute.cs b/Scripts/Runtime/Attributes/SOCItemEditorOptionsAttribute.cs similarity index 71% rename from Scripts/Runtime/Core/SOCItemEditorOptionsAttribute.cs rename to Scripts/Runtime/Attributes/SOCItemEditorOptionsAttribute.cs index fe700c2..fe84fad 100644 --- a/Scripts/Runtime/Core/SOCItemEditorOptionsAttribute.cs +++ b/Scripts/Runtime/Attributes/SOCItemEditorOptionsAttribute.cs @@ -1,4 +1,5 @@ using System; +using UnityEngine; namespace BrunoMikoski.ScriptableObjectCollections { @@ -7,7 +8,17 @@ public enum DrawType Dropdown = 0, AsReference = 1 } - + +#if UNITY_2022_2_OR_NEWER + [Obsolete("DrawAsSOCItemAttribute is not needed anymore, since Unity 2022 PropertyDrawers can be applied to interfaces")] +#endif + [AttributeUsage(AttributeTargets.Field)] + public class DrawAsSOCItemAttribute : PropertyAttribute + { + + } + + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class)] public class SOCItemEditorOptionsAttribute : Attribute { diff --git a/Scripts/Runtime/Core/SOCItemEditorOptionsAttribute.cs.meta b/Scripts/Runtime/Attributes/SOCItemEditorOptionsAttribute.cs.meta similarity index 100% rename from Scripts/Runtime/Core/SOCItemEditorOptionsAttribute.cs.meta rename to Scripts/Runtime/Attributes/SOCItemEditorOptionsAttribute.cs.meta diff --git a/Scripts/Runtime/Core/CollectionItemIndirectReference.cs b/Scripts/Runtime/Core/CollectionItemIndirectReference.cs index b330083..8c9900e 100644 --- a/Scripts/Runtime/Core/CollectionItemIndirectReference.cs +++ b/Scripts/Runtime/Core/CollectionItemIndirectReference.cs @@ -10,7 +10,6 @@ public abstract class CollectionItemIndirectReference: IEquatable new LongGuid(collectionItemGUIDValueA, collectionItemGUIDValueB); @@ -18,7 +17,6 @@ public abstract class CollectionItemIndirectReference: IEquatable new LongGuid(collectionGUIDValueA, collectionGUIDValueB); [SerializeField] diff --git a/Scripts/Runtime/Core/Picker/CollectionItemPicker.cs b/Scripts/Runtime/Core/CollectionItemPicker.cs similarity index 100% rename from Scripts/Runtime/Core/Picker/CollectionItemPicker.cs rename to Scripts/Runtime/Core/CollectionItemPicker.cs diff --git a/Scripts/Runtime/Core/Picker/CollectionItemPicker.cs.meta b/Scripts/Runtime/Core/CollectionItemPicker.cs.meta similarity index 100% rename from Scripts/Runtime/Core/Picker/CollectionItemPicker.cs.meta rename to Scripts/Runtime/Core/CollectionItemPicker.cs.meta diff --git a/Scripts/Runtime/Core/DrawAsSOCItemAttribute.cs b/Scripts/Runtime/Core/DrawAsSOCItemAttribute.cs deleted file mode 100644 index 8113b82..0000000 --- a/Scripts/Runtime/Core/DrawAsSOCItemAttribute.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using UnityEngine; - -namespace BrunoMikoski.ScriptableObjectCollections -{ -#if UNITY_2022_2_OR_NEWER - [Obsolete("DrawAsSOCItemAttribute is not needed anymore, since Unity 2022 PropertyDrawers can be applied to interfaces")] -#endif - [AttributeUsage(AttributeTargets.Field)] - public class DrawAsSOCItemAttribute : PropertyAttribute - { - - } -} diff --git a/Scripts/Runtime/Core/DrawAsSOCItemAttribute.cs.meta b/Scripts/Runtime/Core/DrawAsSOCItemAttribute.cs.meta deleted file mode 100644 index 61e71db..0000000 --- a/Scripts/Runtime/Core/DrawAsSOCItemAttribute.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 382e5f3b7524429684dd50fd2892def2 -timeCreated: 1680709413 \ No newline at end of file diff --git a/Scripts/Runtime/Core/GUID.meta b/Scripts/Runtime/Core/GUID.meta deleted file mode 100644 index f49dab5..0000000 --- a/Scripts/Runtime/Core/GUID.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c9443b17769248f481eca0da80c44b14 -timeCreated: 1680616249 \ No newline at end of file diff --git a/Scripts/Runtime/Core/InitializeCollections.cs b/Scripts/Runtime/Core/InitializeCollections.cs deleted file mode 100644 index e1d20c7..0000000 --- a/Scripts/Runtime/Core/InitializeCollections.cs +++ /dev/null @@ -1,27 +0,0 @@ -using UnityEngine; - -namespace BrunoMikoski.ScriptableObjectCollections -{ - [DefaultExecutionOrder(-10000)] - public class InitializeCollections : MonoBehaviour - { - [SerializeField] - private ScriptableObjectCollection[] collections = new ScriptableObjectCollection[0]; - - private void Awake() - { - for (int i = 0; i < collections.Length; i++) - { - CollectionsRegistry.Instance.RegisterCollection(collections[i]); - } - } - - private void OnDestroy() - { - for (int i = 0; i < collections.Length; i++) - { - CollectionsRegistry.Instance.UnregisterCollection(collections[i]); - } - } - } -} \ No newline at end of file diff --git a/Scripts/Runtime/Core/InitializeCollections.cs.meta b/Scripts/Runtime/Core/InitializeCollections.cs.meta deleted file mode 100644 index d0ba50b..0000000 --- a/Scripts/Runtime/Core/InitializeCollections.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 4e98a53b301c4585889959eb3053451a -timeCreated: 1595705559 \ No newline at end of file diff --git a/Scripts/Runtime/Core/GUID/LongGuid.cs b/Scripts/Runtime/Core/LongGuid.cs similarity index 100% rename from Scripts/Runtime/Core/GUID/LongGuid.cs rename to Scripts/Runtime/Core/LongGuid.cs diff --git a/Scripts/Runtime/Core/GUID/LongGuid.cs.meta b/Scripts/Runtime/Core/LongGuid.cs.meta similarity index 100% rename from Scripts/Runtime/Core/GUID/LongGuid.cs.meta rename to Scripts/Runtime/Core/LongGuid.cs.meta diff --git a/Scripts/Runtime/Core/Picker.meta b/Scripts/Runtime/Core/Picker.meta deleted file mode 100644 index f58175b..0000000 --- a/Scripts/Runtime/Core/Picker.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 635603325aa74c5f9b90a1699c0b2c3d -timeCreated: 1680616112 \ No newline at end of file From 5c9d97c8f32165ddb4c93a6ddf141a87a526c6eb Mon Sep 17 00:00:00 2001 From: Bruno Mikoski Date: Wed, 9 Aug 2023 08:36:19 +0100 Subject: [PATCH 2/4] add: base editor to allow customization of properties --- Scripts/Editor/CustomEditors/BaseEditor.cs | 129 ++++++++++++++++ .../Editor/CustomEditors/BaseEditor.cs.meta | 11 ++ .../CustomEditors/CollectionCustomEditor.cs | 19 ++- Scripts/Editor/Utils/ReflectionUtility.cs | 143 ++++++++++++++++++ .../Editor/Utils/ReflectionUtility.cs.meta | 11 ++ 5 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 Scripts/Editor/CustomEditors/BaseEditor.cs create mode 100644 Scripts/Editor/CustomEditors/BaseEditor.cs.meta create mode 100644 Scripts/Editor/Utils/ReflectionUtility.cs create mode 100644 Scripts/Editor/Utils/ReflectionUtility.cs.meta diff --git a/Scripts/Editor/CustomEditors/BaseEditor.cs b/Scripts/Editor/CustomEditors/BaseEditor.cs new file mode 100644 index 0000000..0336541 --- /dev/null +++ b/Scripts/Editor/CustomEditors/BaseEditor.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using UnityEditor; + +namespace BrunoMikoski.ScriptableObjectCollections +{ + public abstract class BaseEditor : Editor where T : class + { + protected T Target => target as T; + + /// + /// Return the Serialized property for a field, and exclude it from being automatically + /// displayed in the inspector. Call this when you need to provide a custom UX for a field. + /// + /// Magic experssion code + /// Call format is FindAndExcludeProperty(x => x.myField) + /// The serialized property for the field + protected SerializedProperty FindAndExcludeProperty(Expression> expr) + { + SerializedProperty p = FindProperty(expr); + ExcludeProperty(p.name); + return p; + } + + /// + /// Return the Serialized property for a field. + /// + /// Magic experssion code + /// Call format is FindProperty(x => x.myField) + /// The serialized property for the field + protected SerializedProperty FindProperty(Expression> expr) + { + return serializedObject.FindProperty(FieldPath(expr)); + } + + /// + /// Magic code to get the string name of a field. Will not build if the field name changes. + /// + /// Magic experssion code + /// Call format is FieldPath(x => x.myField) + /// The string name of the field + protected string FieldPath(Expression> expr) + { + return ReflectionUtility.GetFieldPath(expr); + } + + /// Obsolete, do not use. Use the overload, which is more performant + /// List of property names to exclude + protected virtual List GetExcludedPropertiesInInspector() { return mExcluded; } + + /// Get the property names to exclude in the inspector. + /// Add the names to this list + protected virtual void GetExcludedPropertiesInInspector(List excluded) + { + excluded.Add("m_Script"); + } + + /// + /// Exclude a property from automatic inclusion in the inspector + /// when DrawRemainingPropertiesInInspector() is called + /// + /// The property to exclude + protected void ExcludeProperty(string propertyName) + { + mExcluded.Add(propertyName); + } + + /// Check whenther a property is in the excluded list + /// The property to check + /// True if property is excluded from automatic inclusion in the inspector + /// when DrawRemainingPropertiesInInspector() is called + protected bool IsPropertyExcluded(string propertyName) + { + return mExcluded.Contains(propertyName); + } + + /// + /// Draw the inspector + /// + public override void OnInspectorGUI() + { + BeginInspector(); + DrawRemainingPropertiesInInspector(); + } + + List mExcluded = new List(); + + /// + /// Clients should call this at the start of OnInspectorGUI. + /// Updates the serialized object and Sets up for excluded properties. + /// + protected virtual void BeginInspector() + { + serializedObject.Update(); + mExcluded.Clear(); + GetExcludedPropertiesInInspector(mExcluded); + } + + /// + /// Draw a property in the inspector, if it is not excluded. + /// Property is marked as drawn, so will not be drawn again + /// by DrawRemainingPropertiesInInspector() + /// + /// The property to draw + protected virtual void DrawPropertyInInspector(SerializedProperty p) + { + if (!IsPropertyExcluded(p.name)) + { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(p); + if (EditorGUI.EndChangeCheck()) + serializedObject.ApplyModifiedProperties(); + ExcludeProperty(p.name); + } + } + + /// + /// Draw all remaining unexcluded undrawn properties in the inspector. + /// + protected void DrawRemainingPropertiesInInspector() + { + EditorGUI.BeginChangeCheck(); + DrawPropertiesExcluding(serializedObject, mExcluded.ToArray()); + if (EditorGUI.EndChangeCheck()) + serializedObject.ApplyModifiedProperties(); + } + } +} \ No newline at end of file diff --git a/Scripts/Editor/CustomEditors/BaseEditor.cs.meta b/Scripts/Editor/CustomEditors/BaseEditor.cs.meta new file mode 100644 index 0000000..e3e7fc9 --- /dev/null +++ b/Scripts/Editor/CustomEditors/BaseEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f250719530626f4fb3db50c8eb30eb7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs b/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs index e8fbc3e..f9cb401 100644 --- a/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs +++ b/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs @@ -12,7 +12,7 @@ namespace BrunoMikoski.ScriptableObjectCollections { [CustomEditor(typeof(ScriptableObjectCollection), true)] - public class CollectionCustomEditor : Editor + public class CollectionCustomEditor : BaseEditor { private const string WAITING_FOR_SCRIPT_TO_BE_CREATED_KEY = "WaitingForScriptTobeCreated"; private static ScriptableObject LAST_ADDED_COLLECTION_ITEM; @@ -83,6 +83,19 @@ protected virtual void OnDisable() reorderableList.drawHeaderCallback -= OnDrawerHeader; } + + protected virtual void HideProperties() + { + ExcludeProperty("guid"); + ExcludeProperty("items"); + ExcludeProperty("automaticallyLoaded"); + ExcludeProperty("generateAsPartialClass"); + ExcludeProperty("generateAsBaseClass"); + ExcludeProperty("generatedFileLocationPath"); + ExcludeProperty("generatedStaticClassFileName"); + ExcludeProperty("generateStaticFileNamespace"); + } + private void OnDrawerHeader(Rect rect) { EditorGUI.LabelField(rect, "Items", EditorStyles.boldLabel); @@ -359,6 +372,9 @@ private void DuplicateItem(int index) public override void OnInspectorGUI() { + base.BeginInspector(); + HideProperties(); + ValidateCollectionItems(); CheckHeightsAndHiddenArraySizes(); @@ -375,6 +391,7 @@ public override void OnInspectorGUI() } DrawSettings(); CheckForKeyboardShortcuts(); + DrawRemainingPropertiesInInspector(); } private void CheckHeightsAndHiddenArraySizes() diff --git a/Scripts/Editor/Utils/ReflectionUtility.cs b/Scripts/Editor/Utils/ReflectionUtility.cs new file mode 100644 index 0000000..fad6c02 --- /dev/null +++ b/Scripts/Editor/Utils/ReflectionUtility.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace BrunoMikoski.ScriptableObjectCollections +{ + public static partial class ReflectionUtility + { + private static Dictionary> typeToModifiableFieldsCache = new Dictionary>(); + private static Dictionary managedReferenceFullTypeNameToTypeCache = new Dictionary(); + + public static Type GetTypeFromManagedFullTypeName(string targetManagedFullTypeName, bool ignoreCache = false) + { + if (!ignoreCache && managedReferenceFullTypeNameToTypeCache.TryGetValue(targetManagedFullTypeName, out Type type)) + return type; + + string[] typeInfo = targetManagedFullTypeName.Split(' '); + type = Type.GetType($"{typeInfo[1]}, {typeInfo[0]}"); + managedReferenceFullTypeNameToTypeCache.Add(targetManagedFullTypeName, type); + + return type; + } + + public static List GetModifiableFields(Type targetType, bool recursive = true, bool ignoreCache = false) + { + if (!ignoreCache && typeToModifiableFieldsCache.TryGetValue(targetType, out List result)) + return result; + + result = new List(); + FieldInfo[] fis = targetType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + for (int i = 0; i < fis.Length; i++) + { + FieldInfo info = fis[i]; + if (info.IsNotSerialized) + continue; + + result.Add(info); + } + + typeToModifiableFieldsCache.Add(targetType, result); + return result; + } + + public static void CopyFields(Object src, object dst, BindingFlags bindingAttr = BindingFlags.Public + | BindingFlags.NonPublic + | BindingFlags.Instance) + { + if (src != null && dst != null) + { + Type type = src.GetType(); + FieldInfo[] fields = type.GetFields(bindingAttr); + for (int i = 0; i < fields.Length; ++i) + if (!fields[i].IsStatic) + fields[i].SetValue(dst, fields[i].GetValue(src)); + } + } + + public static IEnumerable GetTypesInAssembly(Assembly assembly, Predicate predicate) + { + if (assembly == null) + return null; + + Type[] types = new Type[0]; + try + { + types = assembly.GetTypes(); + } + catch (Exception) + { + // Can't load the types in this assembly + } + types = (from t in types + where t != null && predicate(t) + select t).ToArray(); + return types; + } + + public static T AccessInternalField(this Type type, object obj, string memberName) + { + if (string.IsNullOrEmpty(memberName) || (type == null)) + return default(T); + + BindingFlags bindingFlags = BindingFlags.NonPublic; + if (obj != null) + bindingFlags |= BindingFlags.Instance; + else + bindingFlags |= BindingFlags.Static; + + FieldInfo field = type.GetField(memberName, bindingFlags); + if ((field != null) && (field.FieldType == typeof(T))) + return (T)field.GetValue(obj); + + return default(T); + } + + + public static object GetParentObject(string path, object obj) + { + string[] fields = path.Split('.'); + if (fields.Length == 1) + return obj; + + FieldInfo info = obj.GetType().GetField( + fields[0], BindingFlags.Public + | BindingFlags.NonPublic + | BindingFlags.Instance); + obj = info.GetValue(obj); + + return GetParentObject(string.Join(".", fields, 1, fields.Length - 1), obj); + } + + public static string GetFieldPath(Expression> expr) + { + MemberExpression me; + switch (expr.Body.NodeType) + { + case ExpressionType.MemberAccess: + me = expr.Body as MemberExpression; + break; + default: + throw new InvalidOperationException(); + } + + List members = new List(); + while (me != null) + { + members.Add(me.Member.Name); + me = me.Expression as MemberExpression; + } + + StringBuilder sb = new StringBuilder(); + for (int i = members.Count - 1; i >= 0; i--) + { + sb.Append(members[i]); + if (i > 0) sb.Append('.'); + } + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Scripts/Editor/Utils/ReflectionUtility.cs.meta b/Scripts/Editor/Utils/ReflectionUtility.cs.meta new file mode 100644 index 0000000..00e97bd --- /dev/null +++ b/Scripts/Editor/Utils/ReflectionUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15de47dd8df755c46bc459355cbb75e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 45a25867774480720943be6c634c1b719c7caaac Mon Sep 17 00:00:00 2001 From: Bruno Mikoski Date: Tue, 22 Aug 2023 21:54:02 +0100 Subject: [PATCH 3/4] add: more tweaks --- Scripts/Editor/Core/SOCSettings.cs | 32 +++- .../CustomEditors/CollectionCustomEditor.cs | 118 +++++++++---- .../CollectionItemPickerPropertyDrawer.cs | 28 +-- .../Editor/Utils/CopyCollectionItemUtility.cs | 41 ++++- Scripts/Runtime/Core/CollectionItemPicker.cs | 164 +++++++++++++----- Scripts/Runtime/Core/CollectionsRegistry.cs | 16 ++ .../Core/ScriptableObjectCollection.cs | 16 ++ .../Runtime/Extensions/StringExtensions.cs | 3 +- 8 files changed, 323 insertions(+), 95 deletions(-) diff --git a/Scripts/Editor/Core/SOCSettings.cs b/Scripts/Editor/Core/SOCSettings.cs index 65bb616..3cd1855 100644 --- a/Scripts/Editor/Core/SOCSettings.cs +++ b/Scripts/Editor/Core/SOCSettings.cs @@ -65,8 +65,11 @@ public static SOCSettings Instance [SerializeField] private string generatedScriptsDefaultFilePath = @"Assets\Generated\Scripts"; public string GeneratedScriptsDefaultFilePath => generatedScriptsDefaultFilePath; - + [SerializeField] + private List useCustomEditorDrawer = new List(); + + private static readonly GUIContent namespacePrefixGUIContent = new GUIContent( "Prefix", "When using the Create New Collection wizard," + @@ -156,12 +159,37 @@ public void SetGeneratedScriptsDefaultFilePath(string assetPath) generatedScriptsDefaultFilePath = assetPath; Save(); } - + public void Save() { string json = EditorJsonUtility.ToJson(this, prettyPrint: true); File.WriteAllText(STORAGE_PATH, json); } + + public bool ShouldDrawUsingCustomEditor(ScriptableObjectCollection collection) + { + return useCustomEditorDrawer.Contains(collection.GUID); + } + + public void SetUseCustomEditor(ScriptableObjectCollection collection, bool useCustomEditor) + { + if (useCustomEditor) + { + if (!useCustomEditorDrawer.Contains(collection.GUID)) + { + useCustomEditorDrawer.Add(collection.GUID); + Save(); + } + } + else + { + if (useCustomEditorDrawer.Contains(collection.GUID)) + { + useCustomEditorDrawer.Remove(collection.GUID); + Save(); + } + } + } } } diff --git a/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs b/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs index f9cb401..efe2407 100644 --- a/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs +++ b/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs @@ -130,7 +130,7 @@ private void OnClickToAddNewItem(Rect buttonRect, ReorderableList list) private float GetCollectionItemHeight(int index) { if (itemHidden == null || itemHidden.Length == 0 || itemHidden[index] || index > itemHidden.Length - 1) - return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + return 0; return Mathf.Max( heights[index], @@ -169,6 +169,9 @@ private void DrawCollectionItemAtIndex(Rect rect, int index, bool isActive, bool if (Event.current.alt) SetAllExpanded(false); } + + if(wasExpanded != collectionItemSerializedProperty.isExpanded) + itemIndexToRect.Clear(); using (EditorGUI.ChangeCheckScope changeCheck = new EditorGUI.ChangeCheckScope()) { @@ -208,52 +211,91 @@ private void DrawCollectionItemAtIndex(Rect rect, int index, bool isActive, bool if (collectionItemSerializedProperty.isExpanded) { - rect.y += EditorGUIUtility.standardVerticalSpacing; + rect.y += EditorGUIUtility.standardVerticalSpacing; + + if (SOCSettings.Instance.ShouldDrawUsingCustomEditor(collection)) + DrawCustomEditor(ref rect, index, collectionItemSerializedProperty); + else + DrawProperties(ref rect, index, collectionItemSerializedProperty); + } - if (itemIndexToRect.TryGetValue(index, out Rect actualRect) && reorderableListYPosition.HasValue) + CheckForContextInputOnItem(collectionItemSerializedProperty, index, originY, rect); + + heights[index] = rect.y - originY; + } + + private void DrawProperties(ref Rect rect, int index, SerializedProperty collectionItemSerializedProperty) + { + EditorGUI.indentLevel++; + + SerializedObject collectionItemSerializedObject = new SerializedObject(collectionItemSerializedProperty.objectReferenceValue); + SerializedProperty iterator = collectionItemSerializedObject.GetIterator(); + + using (EditorGUI.ChangeCheckScope changeCheck = new EditorGUI.ChangeCheckScope()) + { + for (bool enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false) { - actualRect.y = rect.y + reorderableListYPosition.Value + reorderableList.headerHeight; + bool guiEnabled = GUI.enabled; + if (iterator.displayName.Equals("Script")) + GUI.enabled = false; - // Have to indent the rect here because otherwise it overlaps with the drag handle - EditorGUI.indentLevel++; - actualRect = EditorGUI.IndentedRect(actualRect); - EditorGUI.indentLevel--; + EditorGUI.PropertyField(rect, iterator, true); + GUI.enabled = guiEnabled; + + rect.y += EditorGUI.GetPropertyHeight(iterator, true) + + EditorGUIUtility.standardVerticalSpacing; + } - GUILayout.BeginArea(actualRect); - EditorGUI.indentLevel++; + if (changeCheck.changed) + iterator.serializedObject.ApplyModifiedProperties(); + } + EditorGUI.indentLevel--; + } - Editor editor = EditorCache.GetOrCreateEditorForObject(collectionItemSerializedProperty.objectReferenceValue); - editor.OnInspectorGUI(); + private void DrawCustomEditor(ref Rect rect, int index, SerializedProperty collectionItemSerializedProperty) + { + Editor editor = EditorCache.GetOrCreateEditorForObject(collectionItemSerializedProperty.objectReferenceValue); - EditorGUI.indentLevel--; - GUILayout.EndArea(); + if (itemIndexToRect.TryGetValue(index, out Rect actualRect) && reorderableListYPosition.HasValue) + { + actualRect.y = rect.y + reorderableListYPosition.Value + reorderableList.headerHeight; + + // Have to indent the rect here because otherwise it overlaps with the drag handle + EditorGUI.indentLevel++; + actualRect = EditorGUI.IndentedRect(actualRect); + EditorGUI.indentLevel--; + + GUILayout.BeginArea(actualRect); + EditorGUI.indentLevel++; + EditorGUI.BeginChangeCheck(); + editor.OnInspectorGUI(); + + EditorGUI.indentLevel--; + GUILayout.EndArea(); + + if (EditorGUI.EndChangeCheck()) + { collectionItemSerializedProperty.serializedObject.ApplyModifiedProperties(); - rect.y += actualRect.height; } - else - { - Rect verticalRect = EditorGUILayout.BeginVertical(); - - Editor editor = EditorCache.GetOrCreateEditorForObject(collectionItemSerializedProperty.objectReferenceValue); - editor.OnInspectorGUI(); - EditorGUILayout.EndVertical(); + rect.y += actualRect.height; + } + else + { + Rect verticalRect = EditorGUILayout.BeginVertical(); - if (Event.current.type == EventType.Repaint) - { - itemIndexToRect[index] = verticalRect; - } + editor.OnInspectorGUI(); + + EditorGUILayout.EndVertical(); + + if (Event.current.type == EventType.Repaint) + { + itemIndexToRect[index] = verticalRect; } } - - CheckForContextInputOnItem(collectionItemSerializedProperty, index, originY, rect); - - heights[index] = rect.y - originY; } - - private void SetAllExpanded(bool expanded) { for (int i = 0; i < reorderableList.count; i++) @@ -670,6 +712,8 @@ private void DrawSettings() DrawUseBaseClassToggle(); DrawGeneratedFileName(); DrawGeneratedFileNamespace(); + DrawDrawOptions(); + GUILayout.Space(10); DrawDeleteCollection(); @@ -678,6 +722,16 @@ private void DrawSettings() } } + private void DrawDrawOptions() + { + using EditorGUI.ChangeCheckScope changeCheck = new EditorGUI.ChangeCheckScope(); + bool drawUsingCustomEditor = EditorGUILayout.Toggle("Use Custom Editor", SOCSettings.Instance.ShouldDrawUsingCustomEditor(collection)); + if (changeCheck.changed) + { + SOCSettings.Instance.SetUseCustomEditor(collection, drawUsingCustomEditor); + } + } + private void DrawDeleteCollection() { Color backgroundColor = GUI.backgroundColor; diff --git a/Scripts/Editor/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs b/Scripts/Editor/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs index 3bdddc4..1ed55bf 100644 --- a/Scripts/Editor/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs +++ b/Scripts/Editor/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs @@ -11,10 +11,13 @@ namespace BrunoMikoski.ScriptableObjectCollections.Picker [CustomPropertyDrawer(typeof(CollectionItemPicker<>), true)] public class CollectionItemPickerPropertyDrawer : PropertyDrawer { - private const string LONG_GUID_VALUE_1_PROPERTY_PATH = "value1"; - private const string LONG_GUID_VALUE_2_PROPERTY_PATH = "value2"; + private const string COLLECTION_ITEM_GUID_VALUE_A = "collectionItemGUIDValueA"; + private const string COLLECTION_ITEM_GUID_VALUE_B = "collectionItemGUIDValueB"; - private const string ITEMS_PROPERTY_NAME = "itemsGuids"; + private const string COLLECTION_GUID_VALUE_A = "collectionGUIDValueA"; + private const string COLLECTION_GUID_VALUE_B = "collectionGUIDValueB"; + + private const string ITEMS_PROPERTY_NAME = "cachedIndirectReferences"; private bool initialized; private PopupList popupList = new PopupList(); @@ -174,14 +177,16 @@ private void GetValuesFromPopup(SerializedProperty property) private void AssignItemGUIDToProperty(ScriptableObject scriptableObject, SerializedProperty newProperty) { - SerializedProperty itemGUIDValueASerializedProperty = newProperty.FindPropertyRelative(LONG_GUID_VALUE_1_PROPERTY_PATH); - SerializedProperty itemGUIDValueBSerializedProperty = newProperty.FindPropertyRelative(LONG_GUID_VALUE_2_PROPERTY_PATH); - if (scriptableObject is ISOCItem item) { - (long, long) values = item.GUID.GetRawValues(); - itemGUIDValueASerializedProperty.longValue = values.Item1; - itemGUIDValueBSerializedProperty.longValue = values.Item2; + (long, long) itemValues = item.GUID.GetRawValues(); + (long, long) collectionValues = item.Collection.GUID.GetRawValues(); + + newProperty.FindPropertyRelative(COLLECTION_ITEM_GUID_VALUE_A).longValue = itemValues.Item1; + newProperty.FindPropertyRelative(COLLECTION_ITEM_GUID_VALUE_B).longValue = itemValues.Item2; + + newProperty.FindPropertyRelative(COLLECTION_GUID_VALUE_A).longValue = collectionValues.Item1; + newProperty.FindPropertyRelative(COLLECTION_GUID_VALUE_B).longValue = collectionValues.Item2; } } @@ -198,7 +203,6 @@ private void SetSelectedValuesOnPopup(SerializedProperty property) LongGuid socItemGUID = GetGUIDFromProperty(elementProperty); - ScriptableObject foundItem = availableItems.FirstOrDefault(so => { if (so is ISOCItem item) @@ -232,8 +236,8 @@ private void SetSelectedValuesOnPopup(SerializedProperty property) private LongGuid GetGUIDFromProperty(SerializedProperty property) { - SerializedProperty itemGUIDValueASerializedProperty = property.FindPropertyRelative(LONG_GUID_VALUE_1_PROPERTY_PATH); - SerializedProperty itemGUIDValueBSerializedProperty = property.FindPropertyRelative(LONG_GUID_VALUE_2_PROPERTY_PATH); + SerializedProperty itemGUIDValueASerializedProperty = property.FindPropertyRelative(COLLECTION_ITEM_GUID_VALUE_A); + SerializedProperty itemGUIDValueBSerializedProperty = property.FindPropertyRelative(COLLECTION_ITEM_GUID_VALUE_B); return new LongGuid(itemGUIDValueASerializedProperty.longValue, itemGUIDValueBSerializedProperty.longValue); } diff --git a/Scripts/Editor/Utils/CopyCollectionItemUtility.cs b/Scripts/Editor/Utils/CopyCollectionItemUtility.cs index 07a9c7c..a2a7b41 100644 --- a/Scripts/Editor/Utils/CopyCollectionItemUtility.cs +++ b/Scripts/Editor/Utils/CopyCollectionItemUtility.cs @@ -1,6 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Reflection; using UnityEditor; using UnityEngine; +using Object = UnityEngine.Object; namespace BrunoMikoski.ScriptableObjectCollections { @@ -8,6 +11,8 @@ public static class EditorCache { private static Dictionary typeToEditorCache = new(); + private static Dictionary typeToHasCustomEditorCache = new(); + public static Editor GetOrCreateEditorForObject(Object targetObject) { if (typeToEditorCache.TryGetValue(targetObject, out Editor editor)) @@ -18,7 +23,41 @@ public static Editor GetOrCreateEditorForObject(Object targetObject) return editor; } + public static bool HasCustomEditor(Object objectReferenceValue) + { + Type objectType = objectReferenceValue.GetType(); + if(typeToHasCustomEditorCache.TryGetValue(objectType, out bool hasCustomEditor)) + return hasCustomEditor; + + TypeCache.TypeCollection customEditors = TypeCache.GetTypesWithAttribute(); + + foreach (var type in customEditors) + { + object[] attributes = type.GetCustomAttributes(typeof(CustomEditor), true); + foreach (var attribute in attributes) + { + Type attributeType = attribute.GetType(); + + // Access the `m_InspectedType` field using reflection + FieldInfo fieldInfo = attributeType.GetField("m_InspectedType", BindingFlags.NonPublic | BindingFlags.Instance); + + if (fieldInfo != null) + { + Type inspectedType = fieldInfo.GetValue(attribute) as Type; + + if (inspectedType == objectType || inspectedType.IsSubclassOf(objectType)) + { + typeToHasCustomEditorCache.Add(objectType, true); + return true; + } + } + } + } + typeToHasCustomEditorCache.Add(objectType, false); + return false; + } } + public static class CopyCollectionItemUtility { private static ScriptableObject source; diff --git a/Scripts/Runtime/Core/CollectionItemPicker.cs b/Scripts/Runtime/Core/CollectionItemPicker.cs index bcae679..6373a50 100644 --- a/Scripts/Runtime/Core/CollectionItemPicker.cs +++ b/Scripts/Runtime/Core/CollectionItemPicker.cs @@ -1,7 +1,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using UnityEngine; namespace BrunoMikoski.ScriptableObjectCollections.Picker @@ -11,29 +10,47 @@ namespace BrunoMikoski.ScriptableObjectCollections.Picker /// work if the enum had the [Flags] attribute applied to it. /// [Serializable] - public class CollectionItemPicker : IList + public class CollectionItemPicker : IList, IEquatable>, IEquatable> where TItemType : ScriptableObject, ISOCItem { - [SerializeField] + [SerializeField, Obsolete("Will be removed soon")] private List itemsGuids = new List(); + [SerializeField] + private List> cachedIndirectReferences = new(); + +#pragma warning disable CS0618 // Type or member is obsolete - private bool hasCachedCollection; - private ScriptableObjectCollection cachedCollection; - private ScriptableObjectCollection Collection + private List> indirectReferences { get { - if (!hasCachedCollection) + //Backwards compability with old system + if (itemsGuids.Count > 0) { - hasCachedCollection = CollectionsRegistry.Instance.TryGetCollectionFromItemType(typeof(TItemType), - out cachedCollection); - } + CollectionsRegistry.Instance.TryGetCollectionsOfItemType(out List> results); - return cachedCollection; + for (int i = 0; i < itemsGuids.Count; i++) + { + LongGuid itemGuid = itemsGuids[i]; + for (int j = 0; j < results.Count; j++) + { + ScriptableObjectCollection collection = results[j]; + if (!collection.TryGetItemByGUID(itemGuid, out TItemType result)) + continue; + + cachedIndirectReferences.Add(new CollectionItemIndirectReference(result)); + break; + } + } + itemsGuids.Clear(); + } + + return cachedIndirectReferences; } } - +#pragma warning restore CS0618 // Type or member is obsolete + public event Action OnItemTypeAddedEvent; public event Action OnItemTypeRemovedEvent; public event Action OnChangedEvent; @@ -48,13 +65,9 @@ public List Items { cachedItems.Clear(); - foreach (ScriptableObject sObject in Collection) + for (int i = 0; i < indirectReferences.Count; i++) { - if (sObject is TItemType itemType) - { - if (Contains(itemType)) - cachedItems.Add(itemType); - } + cachedItems.Add(indirectReferences[i].Ref); } isDirty = false; @@ -98,6 +111,17 @@ public bool HasAll(params TItemType[] itemTypes) return true; } + public bool HasAll(IList itemTypes) + { + for (int i = 0; i < itemTypes.Count; i++) + { + if (!Contains(itemTypes[i])) + return false; + } + + return true; + } + public bool HasNone(params TItemType[] itemTypes) { for (int i = 0; i < itemTypes.Length; i++) @@ -195,7 +219,7 @@ public void Add(TItemType item) if (Contains(item)) return; - itemsGuids.Add(item.GUID); + indirectReferences.Add(new CollectionItemIndirectReference(item)); isDirty = true; OnItemTypeAddedEvent?.Invoke(item); OnChangedEvent?.Invoke(); @@ -203,16 +227,17 @@ public void Add(TItemType item) public void Clear() { - itemsGuids.Clear(); + indirectReferences.Clear(); isDirty = true; OnChangedEvent?.Invoke(); } public bool Contains(TItemType item) { - for (int i = 0; i < itemsGuids.Count; i++) + for (int i = 0; i < indirectReferences.Count; i++) { - if (itemsGuids[i] == item.GUID) + CollectionItemIndirectReference indirectReference = indirectReferences[i]; + if (indirectReference.Ref == item) return true; } @@ -221,75 +246,122 @@ public bool Contains(TItemType item) public void CopyTo(TItemType[] array, int arrayIndex) { - for (int i = 0; i < itemsGuids.Count; i++) + for (int i = 0; i < indirectReferences.Count; i++) { - if (!Collection.TryGetItemByGUID(itemsGuids[i], out ScriptableObject item)) - continue; + CollectionItemIndirectReference indirectReference = indirectReferences[i]; + + array[arrayIndex + i] = indirectReference.Ref; - array[arrayIndex + i] = (TItemType) item; } } + private bool TryFindIndirectReferenceByItemType(TItemType targetItemType, out CollectionItemIndirectReference result) + { + for (int i = 0; i < indirectReferences.Count; i++) + { + CollectionItemIndirectReference indirectReference = indirectReferences[i]; + if (indirectReference.Ref == targetItemType) + { + result = indirectReference; + return true; + } + } + + result = null; + return false; + } + public bool Remove(TItemType item) { - TItemType removedItem = item; - bool removed = itemsGuids.Remove(item.GUID); + if (!TryFindIndirectReferenceByItemType(item, out CollectionItemIndirectReference indirectReference)) + return false; + + CollectionItemIndirectReference removedItem = indirectReference; + bool removed = indirectReferences.Remove(indirectReference); if (removed) { isDirty = true; OnChangedEvent?.Invoke(); - OnItemTypeRemovedEvent?.Invoke(removedItem); + OnItemTypeRemovedEvent?.Invoke(removedItem.Ref); } return removed; } - public int Count => itemsGuids.Count; + public int Count => indirectReferences.Count; public bool IsReadOnly => false; public int IndexOf(TItemType item) { - return itemsGuids.IndexOf(item.GUID); + return indirectReferences.FindIndex(reference => reference.Ref.GUID== item.GUID); } public void Insert(int index, TItemType item) { - itemsGuids.Insert(index, item.GUID); + if (Contains(item)) + return; + + indirectReferences.Insert(index, new CollectionItemIndirectReference(item)); isDirty = true; } public void RemoveAt(int index) { - if (index < 0 || index >= itemsGuids.Count) - return; - - if (!Collection.TryGetItemByGUID(itemsGuids[index], out var item)) + if (index < 0 || index >= indirectReferences.Count) return; - TItemType removedItem = (TItemType) item; - itemsGuids.RemoveAt(index); + CollectionItemIndirectReference removedItem = indirectReferences[index]; + indirectReferences.RemoveAt(index); isDirty = true; OnChangedEvent?.Invoke(); - OnItemTypeRemovedEvent?.Invoke(removedItem); + OnItemTypeRemovedEvent?.Invoke(removedItem.Ref); } public TItemType this[int index] { - get - { - if (!Collection.TryGetItemByGUID(itemsGuids[index], out var item)) - return null; - return item as TItemType; - } + get => indirectReferences[index].Ref; set { - itemsGuids[index] = value.GUID; + indirectReferences[index] = new CollectionItemIndirectReference(value); isDirty = true; } } #endregion + public bool Equals(IList other) + { + if (other == null) + return false; + + if (other.Count != Count) + return false; + + for (int i = 0; i < other.Count; i++) + { + if (!Contains(other[i])) + return false; + } + + return true; + } + + public bool Equals(CollectionItemPicker other) + { + if (other == null) + return false; + + if (other.Count != Count) + return false; + + for (int i = 0; i < other.Count; i++) + { + if (!Contains(other[i])) + return false; + } + + return true; + } } } diff --git a/Scripts/Runtime/Core/CollectionsRegistry.cs b/Scripts/Runtime/Core/CollectionsRegistry.cs index 06d5370..4a9629c 100644 --- a/Scripts/Runtime/Core/CollectionsRegistry.cs +++ b/Scripts/Runtime/Core/CollectionsRegistry.cs @@ -169,6 +169,20 @@ public bool TryGetCollectionsOfItemType(out List(out List inputActionMapCollections) where T : ScriptableObjectCollection + { + List result = new List(); + for (int i = 0; i < collections.Count; i++) + { + ScriptableObjectCollection scriptableObjectCollection = collections[i]; + if (scriptableObjectCollection.GetType() == typeof(T)) + result.Add((T)scriptableObjectCollection); + } + + inputActionMapCollections = result; + return result.Count > 0; + } public List GetCollectionsByItemType() where T : ScriptableObjectCollectionItem { @@ -416,6 +430,8 @@ public void SetAutoSearchForCollections(bool isOn) autoSearchForCollections = isOn; ObjectUtility.SetDirty(this); } + + } } diff --git a/Scripts/Runtime/Core/ScriptableObjectCollection.cs b/Scripts/Runtime/Core/ScriptableObjectCollection.cs index 99dacf4..85f0cf3 100644 --- a/Scripts/Runtime/Core/ScriptableObjectCollection.cs +++ b/Scripts/Runtime/Core/ScriptableObjectCollection.cs @@ -210,6 +210,12 @@ public virtual void Sort() ObjectUtility.SetDirty(this); } + public void OrderByName() + { + items = items.OrderBy(o => o.name).ToList(); + ObjectUtility.SetDirty(this); + } + public void Clear() { items.Clear(); @@ -268,6 +274,16 @@ public void RemoveAt(int index) ObjectUtility.SetDirty(this); } + public bool Remove(LongGuid targetGuid) + { + if (TryGetItemByGUID(targetGuid, out ScriptableObject item)) + { + return Remove(item); + } + + return false; + } + object IList.this[int index] { get => this[index]; diff --git a/Scripts/Runtime/Extensions/StringExtensions.cs b/Scripts/Runtime/Extensions/StringExtensions.cs index b7dfdd3..5b704c7 100644 --- a/Scripts/Runtime/Extensions/StringExtensions.cs +++ b/Scripts/Runtime/Extensions/StringExtensions.cs @@ -20,8 +20,7 @@ public static class StringExtensions private const char UNDERSCORE = '_'; private const char DEFAULT_SEPARATOR = ' '; - private static string[] RESERVED_KEYWORDS = - { + private static readonly string[] RESERVED_KEYWORDS = { "abstract", "as", "base", " bool", " break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", From 989b9c0f3c646861f2910d24bc9e212ab1f132ff Mon Sep 17 00:00:00 2001 From: Bruno Mikoski Date: Tue, 22 Aug 2023 22:04:13 +0100 Subject: [PATCH 4/4] add: meta changes --- CHANGELOG.MD | 10 ++++ .../Editor/Utils/CopyCollectionItemUtility.cs | 57 +----------------- Scripts/Editor/Utils/EditorCache.cs | 59 +++++++++++++++++++ package.json | 2 +- 4 files changed, 71 insertions(+), 57 deletions(-) create mode 100644 Scripts/Editor/Utils/EditorCache.cs diff --git a/CHANGELOG.MD b/CHANGELOG.MD index cac4342..dd8b816 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,7 +5,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] + +## [2.0.8] +### Changed - Fixed a small typo in the package description. +- Since [2.0.3] the collection now uses the Editor for drawing the items on the collection, but this can cause some issues depending of how customized it is inside a ReorderableList, so you now can choose the item to use it or not by toggling the `Use Custom Editor` inside the advanced settings +- Upgraded the `CollectionCustomEditor` to use `BaseEditor` +- Updated `CollectionItemPicker<>` to use `IndirectReference<>` to store the items, since also contains the `LongGuid` reference to the Collection, allowing to work with multiple collections of the same time _(It should automatically upgrade to the new version automatically)_ +- Added ability to compare `CollectionItemPicker<>` to a `IList<>` of the same type +- Other small fixes and improvements + ## [2.0.7] ### Changed @@ -459,6 +468,7 @@ public bool IsValidConsumable(Consumable consumable) ### Added - First initial working version +[2.0.8]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.0.8 [2.0.7]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.0.7 [2.0.6]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.0.6 [2.0.5]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.0.5 diff --git a/Scripts/Editor/Utils/CopyCollectionItemUtility.cs b/Scripts/Editor/Utils/CopyCollectionItemUtility.cs index a2a7b41..24581b0 100644 --- a/Scripts/Editor/Utils/CopyCollectionItemUtility.cs +++ b/Scripts/Editor/Utils/CopyCollectionItemUtility.cs @@ -1,63 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using UnityEditor; +using UnityEditor; using UnityEngine; -using Object = UnityEngine.Object; namespace BrunoMikoski.ScriptableObjectCollections { - public static class EditorCache - { - private static Dictionary typeToEditorCache = new(); - - private static Dictionary typeToHasCustomEditorCache = new(); - - public static Editor GetOrCreateEditorForObject(Object targetObject) - { - if (typeToEditorCache.TryGetValue(targetObject, out Editor editor)) - return editor; - - editor = Editor.CreateEditor(targetObject); - typeToEditorCache.Add(targetObject, editor); - return editor; - } - - public static bool HasCustomEditor(Object objectReferenceValue) - { - Type objectType = objectReferenceValue.GetType(); - if(typeToHasCustomEditorCache.TryGetValue(objectType, out bool hasCustomEditor)) - return hasCustomEditor; - - TypeCache.TypeCollection customEditors = TypeCache.GetTypesWithAttribute(); - - foreach (var type in customEditors) - { - object[] attributes = type.GetCustomAttributes(typeof(CustomEditor), true); - foreach (var attribute in attributes) - { - Type attributeType = attribute.GetType(); - - // Access the `m_InspectedType` field using reflection - FieldInfo fieldInfo = attributeType.GetField("m_InspectedType", BindingFlags.NonPublic | BindingFlags.Instance); - - if (fieldInfo != null) - { - Type inspectedType = fieldInfo.GetValue(attribute) as Type; - - if (inspectedType == objectType || inspectedType.IsSubclassOf(objectType)) - { - typeToHasCustomEditorCache.Add(objectType, true); - return true; - } - } - } - } - typeToHasCustomEditorCache.Add(objectType, false); - return false; - } - } - public static class CopyCollectionItemUtility { private static ScriptableObject source; diff --git a/Scripts/Editor/Utils/EditorCache.cs b/Scripts/Editor/Utils/EditorCache.cs new file mode 100644 index 0000000..b05a170 --- /dev/null +++ b/Scripts/Editor/Utils/EditorCache.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using UnityEditor; +using Object = UnityEngine.Object; + +namespace BrunoMikoski.ScriptableObjectCollections +{ + public static class EditorCache + { + private static Dictionary typeToEditorCache = new(); + + private static Dictionary typeToHasCustomEditorCache = new(); + + public static Editor GetOrCreateEditorForObject(Object targetObject) + { + if (typeToEditorCache.TryGetValue(targetObject, out Editor editor)) + return editor; + + editor = Editor.CreateEditor(targetObject); + typeToEditorCache.Add(targetObject, editor); + return editor; + } + + public static bool HasCustomEditor(Object objectReferenceValue) + { + Type objectType = objectReferenceValue.GetType(); + if(typeToHasCustomEditorCache.TryGetValue(objectType, out bool hasCustomEditor)) + return hasCustomEditor; + + TypeCache.TypeCollection customEditors = TypeCache.GetTypesWithAttribute(); + + foreach (var type in customEditors) + { + object[] attributes = type.GetCustomAttributes(typeof(CustomEditor), true); + foreach (var attribute in attributes) + { + Type attributeType = attribute.GetType(); + + // Access the `m_InspectedType` field using reflection + FieldInfo fieldInfo = attributeType.GetField("m_InspectedType", BindingFlags.NonPublic | BindingFlags.Instance); + + if (fieldInfo != null) + { + Type inspectedType = fieldInfo.GetValue(attribute) as Type; + + if (inspectedType == objectType || inspectedType.IsSubclassOf(objectType)) + { + typeToHasCustomEditorCache.Add(objectType, true); + return true; + } + } + } + } + typeToHasCustomEditorCache.Add(objectType, false); + return false; + } + } +} \ No newline at end of file diff --git a/package.json b/package.json index e353d91..9ac43c3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.brunomikoski.scriptableobjectcollection", "displayName": "Scriptable Object Collection", - "version": "2.0.7", + "version": "2.0.8", "unity": "2021.2", "description": "A library to help improve the usability of Unity3D Scriptable Objects by grouping them into a collection and exposing them by code or nice inspectors!", "keywords": [