From 7517e0371b20d0698550a7122e2e7f8f1ac1a92d Mon Sep 17 00:00:00 2001 From: Duncan Waterreus Date: Thu, 2 Sep 2021 09:20:05 +0200 Subject: [PATCH 01/11] Add preserve to AoT helper code, so that it survives code stripping --- Scripts/Runtime/Core/CollectionsRegistry.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Scripts/Runtime/Core/CollectionsRegistry.cs b/Scripts/Runtime/Core/CollectionsRegistry.cs index db99fb9..d69859b 100644 --- a/Scripts/Runtime/Core/CollectionsRegistry.cs +++ b/Scripts/Runtime/Core/CollectionsRegistry.cs @@ -3,6 +3,7 @@ using System.Linq; using BrunoMikoski.ScriptableObjectCollections.Core; using UnityEngine; +using UnityEngine.Scripting; #if UNITY_EDITOR using UnityEditor; #endif @@ -15,6 +16,7 @@ public class CollectionsRegistry : ResourceScriptableObjectSingleton collections = new List(); + [Preserve] public void UsedOnlyForAOTCodeGeneration() { LoadOrCreateInstance(); From 1731168ffab044e232eb5331846849c7d1753850 Mon Sep 17 00:00:00 2001 From: Duncan Waterreus Date: Thu, 2 Sep 2021 09:18:08 +0200 Subject: [PATCH 02/11] Change DrawGotoButton to use the same parameters as DrawEditFoldoutButton --- .../Core/CollectionItemItemPropertyDrawer.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Scripts/Editor/Core/CollectionItemItemPropertyDrawer.cs b/Scripts/Editor/Core/CollectionItemItemPropertyDrawer.cs index fa82241..cd6bf92 100644 --- a/Scripts/Editor/Core/CollectionItemItemPropertyDrawer.cs +++ b/Scripts/Editor/Core/CollectionItemItemPropertyDrawer.cs @@ -82,7 +82,7 @@ internal void DrawCollectionItemDrawer(ref Rect position, ScriptableObjectCollec currentObject = collectionItem; DrawEditFoldoutButton(ref prefixPosition, collectionItem); - DrawGotoButton(ref prefixPosition); + DrawGotoButton(ref prefixPosition, collectionItem); } DrawCollectionItemDropDown(ref prefixPosition, collectionItem, callback); @@ -149,13 +149,7 @@ private void Initialize(SerializedProperty property) Type arrayOrListType = fieldInfo.FieldType.GetArrayOrListType(); Type itemType = arrayOrListType != null ? arrayOrListType : fieldInfo.FieldType; - collectionItemDropdown = new CollectionItemDropdown( - new AdvancedDropdownState(), - itemType - ); - - currentObject = property.serializedObject.targetObject; - initialized = true; + Initialize(itemType, property.serializedObject.targetObject); } internal void Initialize(Type collectionItemType, Object obj) @@ -186,7 +180,7 @@ private void DrawCollectionItemDropDown(ref Rect position, ScriptableObjectColle } } - private void DrawGotoButton(ref Rect popupRect) + private void DrawGotoButton(ref Rect popupRect, ScriptableObjectCollectionItem collectionItem) { Rect buttonRect = popupRect; buttonRect.width = 30; @@ -195,8 +189,8 @@ private void DrawGotoButton(ref Rect popupRect) buttonRect.x += popupRect.width; if (GUI.Button(buttonRect, CollectionEditorGUI.ARROW_RIGHT_CHAR)) { - Selection.activeObject = item.Collection; - CollectionUtility.SetFoldoutOpen(true, item, item.Collection); + Selection.activeObject = collectionItem.Collection; + CollectionUtility.SetFoldoutOpen(true, item, collectionItem.Collection); } } From e8aa81e530d4aad265f9f87e755d99b22ccdc742 Mon Sep 17 00:00:00 2001 From: Duncan Waterreus Date: Thu, 2 Sep 2021 10:48:02 +0200 Subject: [PATCH 03/11] Change CollectionItemItemPropertyDrawer to CollectionItemPropertyDrawer --- .../CollectionItemIndirectReferencePropertyDrawer.cs | 4 ++-- .../Core/CollectionItemItemPropertyDrawer.cs.meta | 3 --- ...pertyDrawer.cs => CollectionItemPropertyDrawer.cs} | 2 +- .../Editor/Core/CollectionItemPropertyDrawer.cs.meta | 11 +++++++++++ 4 files changed, 14 insertions(+), 6 deletions(-) delete mode 100644 Scripts/Editor/Core/CollectionItemItemPropertyDrawer.cs.meta rename Scripts/Editor/Core/{CollectionItemItemPropertyDrawer.cs => CollectionItemPropertyDrawer.cs} (99%) create mode 100644 Scripts/Editor/Core/CollectionItemPropertyDrawer.cs.meta diff --git a/Scripts/Editor/Core/CollectionItemIndirectReferencePropertyDrawer.cs b/Scripts/Editor/Core/CollectionItemIndirectReferencePropertyDrawer.cs index ea0c323..cc96bcd 100644 --- a/Scripts/Editor/Core/CollectionItemIndirectReferencePropertyDrawer.cs +++ b/Scripts/Editor/Core/CollectionItemIndirectReferencePropertyDrawer.cs @@ -12,7 +12,7 @@ public sealed class CollectionItemIndirectReferencePropertyDrawer : PropertyDraw private const string COLLECTION_GUID_PROPERTY_PATh = "collectionGUID"; private Type collectionItemType; - private CollectionItemItemPropertyDrawer collectionItemPropertyDrawer; + private CollectionItemPropertyDrawer collectionItemPropertyDrawer; public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { @@ -25,7 +25,7 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten if (collectionItemPropertyDrawer == null) { - collectionItemPropertyDrawer = new CollectionItemItemPropertyDrawer(); + collectionItemPropertyDrawer = new CollectionItemPropertyDrawer(); collectionItemPropertyDrawer.Initialize(collectionItemType, null); } diff --git a/Scripts/Editor/Core/CollectionItemItemPropertyDrawer.cs.meta b/Scripts/Editor/Core/CollectionItemItemPropertyDrawer.cs.meta deleted file mode 100644 index a62c2f0..0000000 --- a/Scripts/Editor/Core/CollectionItemItemPropertyDrawer.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 6cd39f81f71a4f36a4247570e7f59b62 -timeCreated: 1595444833 \ No newline at end of file diff --git a/Scripts/Editor/Core/CollectionItemItemPropertyDrawer.cs b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs similarity index 99% rename from Scripts/Editor/Core/CollectionItemItemPropertyDrawer.cs rename to Scripts/Editor/Core/CollectionItemPropertyDrawer.cs index cd6bf92..8f66456 100644 --- a/Scripts/Editor/Core/CollectionItemItemPropertyDrawer.cs +++ b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs @@ -7,7 +7,7 @@ namespace BrunoMikoski.ScriptableObjectCollections { [CustomPropertyDrawer(typeof(ScriptableObjectCollectionItem), true)] - public class CollectionItemItemPropertyDrawer : PropertyDrawer + public class CollectionItemPropertyDrawer : PropertyDrawer { private static readonly CollectionItemEditorOptionsAttribute DefaultAttribute = new CollectionItemEditorOptionsAttribute(DrawType.Dropdown); diff --git a/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs.meta b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs.meta new file mode 100644 index 0000000..fe85dac --- /dev/null +++ b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6cd39f81f71a4f36a4247570e7f59b62 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 161a827638f120b2b957725d13c3c114371e4c4a Mon Sep 17 00:00:00 2001 From: Duncan Waterreus Date: Thu, 2 Sep 2021 15:28:00 +0200 Subject: [PATCH 04/11] Add shouldDrawGotoButton and shouldDrawPreviewButton to CollectionItemEditorOptions, use auto-properties --- .../CollectionItemEditorOptionsAttribute.cs | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Scripts/Runtime/Core/CollectionItemEditorOptionsAttribute.cs b/Scripts/Runtime/Core/CollectionItemEditorOptionsAttribute.cs index 77f0c90..dc606bf 100644 --- a/Scripts/Runtime/Core/CollectionItemEditorOptionsAttribute.cs +++ b/Scripts/Runtime/Core/CollectionItemEditorOptionsAttribute.cs @@ -7,20 +7,23 @@ public enum DrawType Dropdown = 0, AsReference = 1 } - - [AttributeUsage(AttributeTargets.Field)] - public class CollectionItemEditorOptionsAttribute :Attribute + + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class)] + public class CollectionItemEditorOptionsAttribute : Attribute { - private DrawType drawType = DrawType.Dropdown; - public DrawType DrawType + public DrawType DrawType { get; set; } = DrawType.Dropdown; + + public bool ShouldDrawGotoButton { get; set; } = true; + + public bool ShouldDrawPreviewButton { get; set; } = true; + + public CollectionItemEditorOptionsAttribute() { - get => drawType; - set => drawType = value; } public CollectionItemEditorOptionsAttribute(DrawType drawType) { - this.drawType = drawType; + DrawType = drawType; } } -} +} \ No newline at end of file From ec6022baac58b939301e4e1e740e7884006a0e62 Mon Sep 17 00:00:00 2001 From: Duncan Waterreus Date: Thu, 2 Sep 2021 15:45:34 +0200 Subject: [PATCH 05/11] Refactored CollectionItemIndirectReferencePropertyDrawer OnGUI into subfunctions for readability Added OptionsAttribute getting and passing through to CollectionItemPropertyDrawer CollectionItemPropertyDrawer to allow for OptionsAttribute to be provided in constructor --- ...tionItemIndirectReferencePropertyDrawer.cs | 141 +++++++++++------- .../Core/CollectionItemPropertyDrawer.cs | 52 +++---- 2 files changed, 112 insertions(+), 81 deletions(-) diff --git a/Scripts/Editor/Core/CollectionItemIndirectReferencePropertyDrawer.cs b/Scripts/Editor/Core/CollectionItemIndirectReferencePropertyDrawer.cs index cc96bcd..3b93508 100644 --- a/Scripts/Editor/Core/CollectionItemIndirectReferencePropertyDrawer.cs +++ b/Scripts/Editor/Core/CollectionItemIndirectReferencePropertyDrawer.cs @@ -9,73 +9,93 @@ namespace BrunoMikoski.ScriptableObjectCollections public sealed class CollectionItemIndirectReferencePropertyDrawer : PropertyDrawer { private const string COLLECTION_ITEM_GUID_PROPERTY_PATH = "collectionItemGUID"; - private const string COLLECTION_GUID_PROPERTY_PATh = "collectionGUID"; + private const string COLLECTION_GUID_PROPERTY_PATH = "collectionGUID"; private Type collectionItemType; private CollectionItemPropertyDrawer collectionItemPropertyDrawer; + private SerializedProperty drawingProperty; + private SerializedProperty itemGUIDSerializedProperty; + private SerializedProperty collectionGUIDSerializedProperty; + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { - if (collectionItemType == null) - { - Type arrayOrListType = fieldInfo.FieldType.GetArrayOrListType(); - Type properFieldType = arrayOrListType ?? fieldInfo.FieldType; - collectionItemType = GetGenericItemType(properFieldType).GetGenericArguments().First(); - } + if(collectionItemType == null) SetCollectionItemType(); + if (collectionItemPropertyDrawer == null) CreateCollectionItemPropertyDrawer(property); - if (collectionItemPropertyDrawer == null) - { - collectionItemPropertyDrawer = new CollectionItemPropertyDrawer(); - collectionItemPropertyDrawer.Initialize(collectionItemType, null); - } - - SerializedProperty collectionItemGUIDSerializedProperty = property.FindPropertyRelative(COLLECTION_ITEM_GUID_PROPERTY_PATH); - SerializedProperty collectionGUIDSerializedProperty = property.FindPropertyRelative(COLLECTION_GUID_PROPERTY_PATh); - - ScriptableObjectCollectionItem collectionItem = null; - - if (!string.IsNullOrEmpty(collectionItemGUIDSerializedProperty.stringValue) - && !string.IsNullOrEmpty(collectionGUIDSerializedProperty.stringValue)) + drawingProperty = property; + itemGUIDSerializedProperty = property.FindPropertyRelative(COLLECTION_ITEM_GUID_PROPERTY_PATH); + collectionGUIDSerializedProperty = property.FindPropertyRelative(COLLECTION_GUID_PROPERTY_PATH); + + var itemGUID = itemGUIDSerializedProperty.stringValue; + var collectionItem = GetCollectionItem(itemGUID, collectionGUIDSerializedProperty.stringValue); + + int indexOfArrayPart = property.propertyPath.IndexOf('['); + if (indexOfArrayPart > -1) { - if (CollectionsRegistry.Instance.TryGetCollectionByGUID(collectionGUIDSerializedProperty.stringValue, - out ScriptableObjectCollection collection)) + if (string.Equals(label.text, itemGUID, StringComparison.Ordinal)) { - if (collection.TryGetItemByGUID(collectionItemGUIDSerializedProperty.stringValue, - out ScriptableObjectCollectionItem resultCollection)) - { - collectionItem = resultCollection; - } + label.text = $"Element {property.propertyPath.Substring(indexOfArrayPart + 1, 1)}"; } } - int indexOfArrayPart = property.propertyPath.IndexOf('['); + if (collectionItemPropertyDrawer.OptionsAttribute.DrawType == DrawType.Dropdown) + { + DrawItemDrawer(position, label, collectionItem); + return; + } - if (indexOfArrayPart > -1) + EditorGUI.PropertyField(position, property, label, true); + } + + private void DrawItemDrawer( + Rect position, GUIContent label, ScriptableObjectCollectionItem collectionItem + ) + { + collectionItemPropertyDrawer.DrawCollectionItemDrawer(ref position, collectionItem, label, item => { - if (string.Equals(label.text, collectionItemGUIDSerializedProperty.stringValue, StringComparison.Ordinal)) - { - label.text = $"Element {property.propertyPath.Substring(indexOfArrayPart+1, 1)}"; - } + SetSerializedPropertyGUIDs(item); + drawingProperty.serializedObject.ApplyModifiedProperties(); + }); + } + + private void SetSerializedPropertyGUIDs(ScriptableObjectCollectionItem item) + { + if (item == null) + { + itemGUIDSerializedProperty.stringValue = string.Empty; + collectionGUIDSerializedProperty.stringValue = string.Empty; } - - collectionItemPropertyDrawer.DrawCollectionItemDrawer( - ref position, collectionItem, label, - item => - { - string collectionItemGUID = string.Empty; - string collectionGUID = string.Empty; - if (item != null) - { - collectionItemGUID = item.GUID; - collectionGUID = item.Collection.GUID; - } - - collectionItemGUIDSerializedProperty.stringValue = collectionItemGUID; - collectionGUIDSerializedProperty.stringValue = collectionGUID; - collectionItem = item; - property.serializedObject.ApplyModifiedProperties(); - } - ); + else + { + itemGUIDSerializedProperty.stringValue = item.GUID; + collectionGUIDSerializedProperty.stringValue = item.Collection.GUID; + } + } + + private static ScriptableObjectCollectionItem GetCollectionItem(string itemGUID, string collectionGUID) + { + if (string.IsNullOrEmpty(itemGUID)) return null; + if (string.IsNullOrEmpty(collectionGUID)) return null; + if (!CollectionsRegistry.Instance.TryGetCollectionByGUID(collectionGUID, + out ScriptableObjectCollection collection)) + return null; + if (!collection.TryGetItemByGUID(itemGUID, out ScriptableObjectCollectionItem resultCollection)) + return null; + return resultCollection; + } + + private void CreateCollectionItemPropertyDrawer(SerializedProperty serializedProperty) + { + collectionItemPropertyDrawer = new CollectionItemPropertyDrawer(); + collectionItemPropertyDrawer.Initialize(collectionItemType, GetOptionsAttribute()); + } + + private void SetCollectionItemType() + { + Type arrayOrListType = fieldInfo.FieldType.GetArrayOrListType(); + Type properFieldType = arrayOrListType ?? fieldInfo.FieldType; + collectionItemType = GetGenericItemType(properFieldType).GetGenericArguments().First(); } private Type GetGenericItemType(Type targetType) @@ -84,12 +104,23 @@ private Type GetGenericItemType(Type targetType) while (baseType != null) { - if (baseType.IsGenericType && baseType.GetGenericTypeDefinition() == typeof(CollectionItemIndirectReference<>)) + if (baseType.IsGenericType && + baseType.GetGenericTypeDefinition() == typeof(CollectionItemIndirectReference<>)) return baseType; baseType = baseType.BaseType; } + return null; } - } -} + private CollectionItemEditorOptionsAttribute GetOptionsAttribute() + { + if (fieldInfo == null) + return null; + object[] attributes = fieldInfo.GetCustomAttributes(typeof(CollectionItemEditorOptionsAttribute), false); + if (attributes.Length > 0) + return attributes[0] as CollectionItemEditorOptionsAttribute; + return null; + } + } +} \ No newline at end of file diff --git a/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs index 8f66456..cb59add 100644 --- a/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs +++ b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs @@ -12,20 +12,10 @@ public class CollectionItemPropertyDrawer : PropertyDrawer private static readonly CollectionItemEditorOptionsAttribute DefaultAttribute = new CollectionItemEditorOptionsAttribute(DrawType.Dropdown); - private CollectionItemEditorOptionsAttribute cachedOptionsAttribute; - - private CollectionItemEditorOptionsAttribute OptionsAttribute - { - get - { - if (cachedOptionsAttribute == null) - cachedOptionsAttribute = GetOptionsAttribute(); - return cachedOptionsAttribute; - } - } + internal CollectionItemEditorOptionsAttribute OptionsAttribute { get; private set; } private bool initialized; - + private Object currentObject; private CollectionItemDropdown collectionItemDropdown; @@ -36,8 +26,7 @@ private CollectionItemEditorOptionsAttribute GetOptionsAttribute() { if (fieldInfo == null) return DefaultAttribute; - object[] attributes - = fieldInfo.GetCustomAttributes(typeof(CollectionItemEditorOptionsAttribute), false); + object[] attributes = fieldInfo.GetCustomAttributes(typeof(CollectionItemEditorOptionsAttribute), false); if (attributes.Length > 0) return attributes[0] as CollectionItemEditorOptionsAttribute; return DefaultAttribute; @@ -51,11 +40,11 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { Initialize(property); - + if (OptionsAttribute.DrawType == DrawType.AsReference) { EditorGUI.PropertyField(position, property, label, true); - return; + return; } item = property.objectReferenceValue as ScriptableObjectCollectionItem; @@ -80,7 +69,7 @@ internal void DrawCollectionItemDrawer(ref Rect position, ScriptableObjectCollec { if (currentObject == null) currentObject = collectionItem; - + DrawEditFoldoutButton(ref prefixPosition, collectionItem); DrawGotoButton(ref prefixPosition, collectionItem); } @@ -95,7 +84,7 @@ private void DrawEditorPreview(ref Rect rect, ScriptableObjectCollectionItem scr { if (scriptableObjectCollectionItem == null) return; - + if (!CollectionUtility.IsFoldoutOpen(scriptableObjectCollectionItem, currentObject)) return; @@ -107,7 +96,7 @@ private void DrawEditorPreview(ref Rect rect, ScriptableObjectCollectionItem scr SerializedObject collectionItemSerializedObject = new SerializedObject(scriptableObjectCollectionItem); EditorGUI.indentLevel++; - rect = EditorGUI.IndentedRect(rect); + rect = EditorGUI.IndentedRect(rect); SerializedProperty iterator = collectionItemSerializedObject.GetIterator(); using (EditorGUI.ChangeCheckScope changeCheck = new EditorGUI.ChangeCheckScope()) @@ -134,7 +123,7 @@ private void DrawEditorPreview(ref Rect rect, ScriptableObjectCollectionItem scr Rect boxPosition = rect; boxPosition.y = beginPositionY - 5; - boxPosition.height = (rect.y - beginPositionY)+10; + boxPosition.height = (rect.y - beginPositionY) + 10; boxPosition.width += 10; boxPosition.x += 5; rect.y += 10; @@ -145,25 +134,33 @@ private void Initialize(SerializedProperty property) { if (initialized) return; - + Type arrayOrListType = fieldInfo.FieldType.GetArrayOrListType(); Type itemType = arrayOrListType != null ? arrayOrListType : fieldInfo.FieldType; Initialize(itemType, property.serializedObject.targetObject); } - internal void Initialize(Type collectionItemType, Object obj) + internal void Initialize(Type collectionItemType, CollectionItemEditorOptionsAttribute optionsAttribute) + { + Initialize(collectionItemType, (Object)null); + OptionsAttribute = optionsAttribute; + } + + internal virtual void Initialize(Type collectionItemType, Object obj) { if (initialized) return; - + collectionItemDropdown = new CollectionItemDropdown( new AdvancedDropdownState(), collectionItemType ); - + currentObject = obj; initialized = true; + + OptionsAttribute = GetOptionsAttribute(); } private void DrawCollectionItemDropDown(ref Rect position, ScriptableObjectCollectionItem collectionItem, @@ -173,7 +170,7 @@ private void DrawCollectionItemDropDown(ref Rect position, ScriptableObjectColle if (collectionItem != null) displayValue = new GUIContent(collectionItem.name); - + if (GUI.Button(position, displayValue, EditorStyles.popup)) { collectionItemDropdown.Show(position, callback.Invoke); @@ -182,6 +179,8 @@ private void DrawCollectionItemDropDown(ref Rect position, ScriptableObjectColle private void DrawGotoButton(ref Rect popupRect, ScriptableObjectCollectionItem collectionItem) { + if (!OptionsAttribute.ShouldDrawGotoButton) return; + Rect buttonRect = popupRect; buttonRect.width = 30; buttonRect.height = 18; @@ -196,6 +195,8 @@ private void DrawGotoButton(ref Rect popupRect, ScriptableObjectCollectionItem c private void DrawEditFoldoutButton(ref Rect popupRect, ScriptableObjectCollectionItem targetItem) { + if (!OptionsAttribute.ShouldDrawPreviewButton) return; + Rect buttonRect = popupRect; buttonRect.width = 30; buttonRect.height = 18; @@ -212,6 +213,5 @@ private void DrawEditFoldoutButton(ref Rect popupRect, ScriptableObjectCollectio ObjectUtility.SetDirty(targetItem); } } - } } From 3496f6d31aabb3dee133424c06517d59850cb05c Mon Sep 17 00:00:00 2001 From: Duncan Waterreus Date: Thu, 2 Sep 2021 15:46:12 +0200 Subject: [PATCH 06/11] Fix T is also used as the Type variable of the class by using TInstance instead of T --- .../Core/ResourceScriptableObjectSingleton.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Scripts/Runtime/Core/ResourceScriptableObjectSingleton.cs b/Scripts/Runtime/Core/ResourceScriptableObjectSingleton.cs index 7ab2734..7585d25 100644 --- a/Scripts/Runtime/Core/ResourceScriptableObjectSingleton.cs +++ b/Scripts/Runtime/Core/ResourceScriptableObjectSingleton.cs @@ -17,17 +17,17 @@ public static T Instance } [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] - public static T LoadOrCreateInstance() where T : ScriptableObject + public static TInstance LoadOrCreateInstance() where TInstance : ScriptableObject { - if (!TryToLoadInstance(out T resultInstance)) + if (!TryToLoadInstance(out TInstance resultInstance)) { #if !UNITY_EDITOR return null; #else - resultInstance = CreateInstance(); + resultInstance = CreateInstance(); AssetDatabaseUtils.CreatePathIfDontExist("Assets/Resources"); - UnityEditor.AssetDatabase.CreateAsset(resultInstance, $"Assets/Resources/{typeof(T).Name}.asset"); + UnityEditor.AssetDatabase.CreateAsset(resultInstance, $"Assets/Resources/{typeof(TInstance).Name}.asset"); UnityEditor.AssetDatabase.SaveAssets(); UnityEditor.AssetDatabase.Refresh(); return resultInstance; @@ -42,9 +42,9 @@ public static bool Exist() return TryToLoadInstance(out _); } - private static bool TryToLoadInstance(out T result) where T: ScriptableObject + private static bool TryToLoadInstance(out TInstance result) where TInstance: ScriptableObject { - T newInstance = Resources.Load(typeof(T).Name); + TInstance newInstance = Resources.Load(typeof(TInstance).Name); if (newInstance != null) { @@ -53,12 +53,12 @@ private static bool TryToLoadInstance(out T result) where T: ScriptableObject } #if UNITY_EDITOR - string registryGUID = UnityEditor.AssetDatabase.FindAssets($"t:{typeof(T).Name}") + string registryGUID = UnityEditor.AssetDatabase.FindAssets($"t:{typeof(TInstance).Name}") .FirstOrDefault(); if (!string.IsNullOrEmpty(registryGUID)) { - newInstance = (T) UnityEditor.AssetDatabase.LoadAssetAtPath( + newInstance = (TInstance) UnityEditor.AssetDatabase.LoadAssetAtPath( UnityEditor.AssetDatabase.GUIDToAssetPath(registryGUID)); } From 5e758afd44816a563f203c595513a16e048d7d1b Mon Sep 17 00:00:00 2001 From: Duncan Waterreus Date: Thu, 2 Sep 2021 16:00:15 +0200 Subject: [PATCH 07/11] Fix DrawGotoButton to use the same collectionItem for both CollectionUtility.SetFoldoutOpen parameters --- Scripts/Editor/Core/CollectionItemPropertyDrawer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs index cb59add..f6823f3 100644 --- a/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs +++ b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs @@ -189,7 +189,7 @@ private void DrawGotoButton(ref Rect popupRect, ScriptableObjectCollectionItem c if (GUI.Button(buttonRect, CollectionEditorGUI.ARROW_RIGHT_CHAR)) { Selection.activeObject = collectionItem.Collection; - CollectionUtility.SetFoldoutOpen(true, item, collectionItem.Collection); + CollectionUtility.SetFoldoutOpen(true, collectionItem, collectionItem.Collection); } } From c64c5a9c763a7242a74c53806ddb8a4ea22433c1 Mon Sep 17 00:00:00 2001 From: Duncan Waterreus Date: Thu, 2 Sep 2021 16:04:37 +0200 Subject: [PATCH 08/11] Fix Initialize with null OptionsAttribute to fallback to default --- Scripts/Editor/Core/CollectionItemPropertyDrawer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs index f6823f3..723b4b2 100644 --- a/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs +++ b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs @@ -144,7 +144,7 @@ private void Initialize(SerializedProperty property) internal void Initialize(Type collectionItemType, CollectionItemEditorOptionsAttribute optionsAttribute) { Initialize(collectionItemType, (Object)null); - OptionsAttribute = optionsAttribute; + OptionsAttribute = optionsAttribute ?? GetOptionsAttribute(); } internal virtual void Initialize(Type collectionItemType, Object obj) From a32a3173699c8a1369a085cd745b8626873c9aa9 Mon Sep 17 00:00:00 2001 From: Duncan Waterreus Date: Thu, 2 Sep 2021 16:14:41 +0200 Subject: [PATCH 09/11] Fix removed virtualization from Initialize --- Scripts/Editor/Core/CollectionItemPropertyDrawer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs index 723b4b2..d8c4d8d 100644 --- a/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs +++ b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs @@ -147,7 +147,7 @@ internal void Initialize(Type collectionItemType, CollectionItemEditorOptionsAtt OptionsAttribute = optionsAttribute ?? GetOptionsAttribute(); } - internal virtual void Initialize(Type collectionItemType, Object obj) + internal void Initialize(Type collectionItemType, Object obj) { if (initialized) return; From d34bd5e536c7ef7e4b594dab983dc9d845073bd7 Mon Sep 17 00:00:00 2001 From: Duncan Waterreus Date: Fri, 3 Sep 2021 12:24:00 +0200 Subject: [PATCH 10/11] Fix issue with GetAllCollectionItemsOfType to select and cast to Types that Match, as inherited & generic types had some edge cases causing invalid casts --- Scripts/Runtime/Core/CollectionsRegistry.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Scripts/Runtime/Core/CollectionsRegistry.cs b/Scripts/Runtime/Core/CollectionsRegistry.cs index d69859b..544e01d 100644 --- a/Scripts/Runtime/Core/CollectionsRegistry.cs +++ b/Scripts/Runtime/Core/CollectionsRegistry.cs @@ -13,7 +13,7 @@ namespace BrunoMikoski.ScriptableObjectCollections [DefaultExecutionOrder(-1000)] public class CollectionsRegistry : ResourceScriptableObjectSingleton { - [SerializeField] + [SerializeField] private List collections = new List(); [Preserve] @@ -58,7 +58,7 @@ public void UnregisterCollection(ScriptableObjectCollection targetCollection) public List GetAllCollectionItemsOfType() where T : ScriptableObjectCollectionItem { - return GetAllCollectionItemsOfType(typeof(T)).Cast().ToList(); + return GetAllCollectionItemsOfType(typeof(T)).OfType().ToList(); } public List GetAllCollectionItemsOfType(Type itemType) @@ -75,7 +75,7 @@ public List GetAllCollectionItemsOfType(Type ite return results; } - + public List GetCollectionsByItemType() where T : ScriptableObjectCollectionItem { return GetCollectionsByItemType(typeof(T)); @@ -96,7 +96,7 @@ public List GetCollectionsByItemType(Type targetColl return result; } - + public ScriptableObjectCollection GetCollectionByGUID(string guid) { for (int i = 0; i < collections.Count; i++) @@ -170,7 +170,7 @@ public bool TryGetCollectionFromItemType(out ScriptableObjectCollect scriptableObjectCollection = null; return false; } - + public bool TryGetCollectionByGUID(string targetGUID, out ScriptableObjectCollection resultCollection) { for (int i = 0; i < collections.Count; i++) @@ -296,14 +296,14 @@ public void PostBuildProcess() { ReloadCollections(); } - + #if UNITY_EDITOR public void PrepareForPlayMode() { for (int i = 0; i < collections.Count; i++) collections[i].PrepareForPlayMode(); } - + public void PrepareForEditorMode() { for (int i = 0; i < collections.Count; i++) From 0041fb8de7830d4943decc2ee73319e3c05aa65e Mon Sep 17 00:00:00 2001 From: Duncan Waterreus Date: Fri, 3 Sep 2021 12:02:46 +0200 Subject: [PATCH 11/11] Fix FieldInfo being null when drawn through a Property by using reflection --- .../Core/CollectionItemPropertyDrawer.cs | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs index d8c4d8d..1d9b08a 100644 --- a/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs +++ b/Scripts/Editor/Core/CollectionItemPropertyDrawer.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using UnityEditor; using UnityEditor.IMGUI.Controls; using UnityEngine; @@ -135,12 +136,35 @@ private void Initialize(SerializedProperty property) if (initialized) return; - Type arrayOrListType = fieldInfo.FieldType.GetArrayOrListType(); - Type itemType = arrayOrListType != null ? arrayOrListType : fieldInfo.FieldType; - + Type itemType; + if (fieldInfo == null) + { + Type parentType = property.serializedObject.targetObject.GetType(); + itemType = GetFieldViaPath(parentType, property.propertyPath).FieldType; + } + else + { + Type arrayOrListType = fieldInfo.FieldType.GetArrayOrListType(); + itemType = arrayOrListType ?? fieldInfo.FieldType; + } + Initialize(itemType, property.serializedObject.targetObject); } + public static System.Reflection.FieldInfo GetFieldViaPath(Type parentType, string path) + { + FieldInfo fieldInfo = parentType.GetField(path); + string[] perDot = path.Split('.'); + foreach (string fieldName in perDot) + { + fieldInfo = parentType.GetField(fieldName); + if (fieldInfo == null) return null; + parentType = fieldInfo.FieldType; + } + + return fieldInfo; + } + internal void Initialize(Type collectionItemType, CollectionItemEditorOptionsAttribute optionsAttribute) { Initialize(collectionItemType, (Object)null);