From dc746626dd7127656807e4f4c43e833ca4d2d471 Mon Sep 17 00:00:00 2001 From: Lucas Baran Date: Fri, 18 Apr 2025 14:07:40 +0200 Subject: [PATCH 01/11] remove the weird SubClassPickerAttributeDrawer component and rename the file to SubClassPickerDrawer --- .../SubClassPickerAttributeDrawer.cs | 81 ------------------- .../AttributesDrawer/SubClassPickerDrawer.cs | 78 ++++++++++++++++++ ...r.cs.meta => SubClassPickerDrawer.cs.meta} | 0 3 files changed, 78 insertions(+), 81 deletions(-) delete mode 100644 Editor/PropertyDrawer/AttributesDrawer/SubClassPickerAttributeDrawer.cs create mode 100644 Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs rename Editor/PropertyDrawer/AttributesDrawer/{SubClassPickerAttributeDrawer.cs.meta => SubClassPickerDrawer.cs.meta} (100%) diff --git a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerAttributeDrawer.cs b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerAttributeDrawer.cs deleted file mode 100644 index eecfab6..0000000 --- a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerAttributeDrawer.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEditor; -using UnityEngine; - -namespace FishingCactus.CommonCode -{ - public class SubClassPickerAttributeDrawer : MonoBehaviour - { - [CustomPropertyDrawer( typeof( SubClassPicker ) )] - public class SubClassPickerDrawer : PropertyDrawer - { - // -- FIELDS - - private const string DefaultDisplay = "Pick a type"; - - // -- METHODS - - private IEnumerable GetSubClasses( - Type base_type - ) - { - return Assembly.GetAssembly( base_type ) - .GetTypes() - .Where( type => type.IsClass && !type.IsAbstract && base_type.IsAssignableFrom( type ) ); - } - - // -- UNITY - - public override float GetPropertyHeight( - SerializedProperty property, - GUIContent label - ) - { - return EditorGUI.GetPropertyHeight( property, label ); - } - - public override void OnGUI( - Rect position, - SerializedProperty property, - GUIContent label - ) - { - Type field_type = fieldInfo.FieldType; - - string type_name = property.managedReferenceValue?.GetType().Name ?? DefaultDisplay; - - Rect drop_down_rect = position; - - drop_down_rect.x += EditorGUIUtility.labelWidth + 2; - drop_down_rect.width -= EditorGUIUtility.labelWidth + 2; - drop_down_rect.height = EditorGUIUtility.singleLineHeight; - - if( EditorGUI.DropdownButton( drop_down_rect, new( type_name ), FocusType.Keyboard ) ) - { - GenericMenu menu = new GenericMenu(); - menu.AddItem( new GUIContent( "None" ), property.managedReferenceValue == null, () => - { - property.managedReferenceValue = null; - property.serializedObject.ApplyModifiedProperties(); - } ); - - foreach( Type type in GetSubClasses( field_type ) ) - { - menu.AddItem( new GUIContent( type.Name ), type_name == type.Name, () => - { - property.managedReferenceValue = type.GetConstructor( Type.EmptyTypes ).Invoke( null ); - property.serializedObject.ApplyModifiedProperties(); - } ); - - menu.ShowAsContext(); - } - } - - EditorGUI.PropertyField( position, property, label, true ); - } - } - } -} \ No newline at end of file diff --git a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs new file mode 100644 index 0000000..cfc2e0d --- /dev/null +++ b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; + +namespace FishingCactus.CommonCode +{ + [CustomPropertyDrawer( typeof( SubClassPicker ) )] + public class SubClassPickerDrawer : PropertyDrawer + { + // -- FIELDS + + private const string DefaultDisplay = "Pick a type"; + + // -- METHODS + + private IEnumerable GetSubClasses( + Type base_type + ) + { + return Assembly.GetAssembly( base_type ) + .GetTypes() + .Where( type => type.IsClass && !type.IsAbstract && base_type.IsAssignableFrom( type ) ); + } + + // -- UNITY + + public override float GetPropertyHeight( + SerializedProperty property, + GUIContent label + ) + { + return EditorGUI.GetPropertyHeight( property, label ); + } + + public override void OnGUI( + Rect position, + SerializedProperty property, + GUIContent label + ) + { + Type field_type = fieldInfo.FieldType; + + string type_name = property.managedReferenceValue?.GetType().Name ?? DefaultDisplay; + + Rect drop_down_rect = position; + + drop_down_rect.x += EditorGUIUtility.labelWidth + 2; + drop_down_rect.width -= EditorGUIUtility.labelWidth + 2; + drop_down_rect.height = EditorGUIUtility.singleLineHeight; + + if( EditorGUI.DropdownButton( drop_down_rect, new( type_name ), FocusType.Keyboard ) ) + { + GenericMenu menu = new GenericMenu(); + menu.AddItem( new GUIContent( "None" ), property.managedReferenceValue == null, () => + { + property.managedReferenceValue = null; + property.serializedObject.ApplyModifiedProperties(); + } ); + + foreach( Type type in GetSubClasses( field_type ) ) + { + menu.AddItem( new GUIContent( type.Name ), type_name == type.Name, () => + { + property.managedReferenceValue = type.GetConstructor( Type.EmptyTypes ).Invoke( null ); + property.serializedObject.ApplyModifiedProperties(); + } ); + + menu.ShowAsContext(); + } + } + + EditorGUI.PropertyField( position, property, label, true ); + } + } +} \ No newline at end of file diff --git a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerAttributeDrawer.cs.meta b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs.meta similarity index 100% rename from Editor/PropertyDrawer/AttributesDrawer/SubClassPickerAttributeDrawer.cs.meta rename to Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs.meta From f7d616f6f91a4b263d17b94f907f421a4e373948 Mon Sep 17 00:00:00 2001 From: Lucas Baran Date: Fri, 18 Apr 2025 14:08:24 +0200 Subject: [PATCH 02/11] SubClassPickerDrawer: remove comments --- .../PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs index cfc2e0d..5950ce3 100644 --- a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs +++ b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs @@ -10,12 +10,8 @@ namespace FishingCactus.CommonCode [CustomPropertyDrawer( typeof( SubClassPicker ) )] public class SubClassPickerDrawer : PropertyDrawer { - // -- FIELDS - private const string DefaultDisplay = "Pick a type"; - // -- METHODS - private IEnumerable GetSubClasses( Type base_type ) @@ -25,8 +21,6 @@ Type base_type .Where( type => type.IsClass && !type.IsAbstract && base_type.IsAssignableFrom( type ) ); } - // -- UNITY - public override float GetPropertyHeight( SerializedProperty property, GUIContent label From 0d6ba12bfa413f3c58de727328c2d0a4a766993b Mon Sep 17 00:00:00 2001 From: Lucas Baran Date: Fri, 18 Apr 2025 14:13:26 +0200 Subject: [PATCH 03/11] SubClassPickerDrawer: use TypCache to get derived types from any assemblies --- .../PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs index 5950ce3..44d840e 100644 --- a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs +++ b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; using UnityEditor; using UnityEngine; @@ -16,9 +15,8 @@ private IEnumerable GetSubClasses( Type base_type ) { - return Assembly.GetAssembly( base_type ) - .GetTypes() - .Where( type => type.IsClass && !type.IsAbstract && base_type.IsAssignableFrom( type ) ); + return TypeCache.GetTypesDerivedFrom( base_type ) + .Where( type => type.IsClass && !type.IsAbstract ); } public override float GetPropertyHeight( From 242923161c0c6281c63b67f1cd8cc3c1acb11cde Mon Sep 17 00:00:00 2001 From: Lucas Baran Date: Fri, 18 Apr 2025 14:31:51 +0200 Subject: [PATCH 04/11] SubClassPickerDrawer: show context menu only once for all options --- .../PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs index 44d840e..b4b1576 100644 --- a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs +++ b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs @@ -59,9 +59,9 @@ GUIContent label property.managedReferenceValue = type.GetConstructor( Type.EmptyTypes ).Invoke( null ); property.serializedObject.ApplyModifiedProperties(); } ); - - menu.ShowAsContext(); } + + menu.ShowAsContext(); } EditorGUI.PropertyField( position, property, label, true ); From 4d9cee80683e57801af7d143f6f3a65e725c0c36 Mon Sep 17 00:00:00 2001 From: Lucas Baran Date: Fri, 18 Apr 2025 14:33:29 +0200 Subject: [PATCH 05/11] ReflectionUtils: add IsCollectionType function --- Runtime/Utilities/ReflectionUtils.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Runtime/Utilities/ReflectionUtils.cs b/Runtime/Utilities/ReflectionUtils.cs index 7c33f3e..f6396f3 100644 --- a/Runtime/Utilities/ReflectionUtils.cs +++ b/Runtime/Utilities/ReflectionUtils.cs @@ -41,6 +41,14 @@ out Type element_type return false; } + public static bool IsCollectionType( + Type list_type + ) + { + return list_type.IsArray + || ( list_type.IsGenericType && IsAssignableToGenericType( list_type, typeof( IEnumerable<> ) ) ); + } + public static bool IsAssignableToGenericType( Type type, Type generic_type From d6b2973e830f3697604cf5db4791c3d9dad5a77d Mon Sep 17 00:00:00 2001 From: Lucas Baran Date: Fri, 18 Apr 2025 14:34:30 +0200 Subject: [PATCH 06/11] SubClassPickerDrawer: get base type from collections --- .../AttributesDrawer/SubClassPickerDrawer.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs index b4b1576..f6bb89b 100644 --- a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs +++ b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs @@ -15,6 +15,13 @@ private IEnumerable GetSubClasses( Type base_type ) { + if( ReflectionUtils.IsCollectionType( base_type ) + && !ReflectionUtils.TryGetEnumerableElementType( base_type, out base_type ) + ) + { + return Enumerable.Empty(); + } + return TypeCache.GetTypesDerivedFrom( base_type ) .Where( type => type.IsClass && !type.IsAbstract ); } From 64ddf7f93d7b7c84ceaa48814f9b6b5c8671db67 Mon Sep 17 00:00:00 2001 From: Lucas Baran Date: Fri, 18 Apr 2025 16:10:03 +0200 Subject: [PATCH 07/11] SubClassPickerDrawer: show mixed values when multiple values are selected --- .../PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs index f6bb89b..66b82f5 100644 --- a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs +++ b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs @@ -50,6 +50,9 @@ GUIContent label drop_down_rect.width -= EditorGUIUtility.labelWidth + 2; drop_down_rect.height = EditorGUIUtility.singleLineHeight; + bool previous_show_mixed_values = EditorGUI.showMixedValue; + EditorGUI.showMixedValue = property.hasMultipleDifferentValues; + if( EditorGUI.DropdownButton( drop_down_rect, new( type_name ), FocusType.Keyboard ) ) { GenericMenu menu = new GenericMenu(); @@ -72,6 +75,8 @@ GUIContent label } EditorGUI.PropertyField( position, property, label, true ); + + EditorGUI.showMixedValue = previous_show_mixed_values; } } } \ No newline at end of file From d223646a8d9eb4455577b803e5ff235f33728892 Mon Sep 17 00:00:00 2001 From: Lucas Baran Date: Fri, 18 Apr 2025 18:08:34 +0200 Subject: [PATCH 08/11] SubClassPickerDrawer: disable picker when there are multiple values --- .../AttributesDrawer/SubClassPickerDrawer.cs | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs index 66b82f5..25b5035 100644 --- a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs +++ b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs @@ -53,25 +53,29 @@ GUIContent label bool previous_show_mixed_values = EditorGUI.showMixedValue; EditorGUI.showMixedValue = property.hasMultipleDifferentValues; - if( EditorGUI.DropdownButton( drop_down_rect, new( type_name ), FocusType.Keyboard ) ) + using( new EditorGUI.DisabledGroupScope( property.hasMultipleDifferentValues ) ) { - GenericMenu menu = new GenericMenu(); - menu.AddItem( new GUIContent( "None" ), property.managedReferenceValue == null, () => + if( EditorGUI.DropdownButton( drop_down_rect, new( type_name ), FocusType.Keyboard ) ) { - property.managedReferenceValue = null; - property.serializedObject.ApplyModifiedProperties(); - } ); - - foreach( Type type in GetSubClasses( field_type ) ) - { - menu.AddItem( new GUIContent( type.Name ), type_name == type.Name, () => + Debug.Log( property.managedReferenceId ); + GenericMenu menu = new GenericMenu(); + menu.AddItem( new GUIContent( "None" ), property.managedReferenceValue == null, () => { - property.managedReferenceValue = type.GetConstructor( Type.EmptyTypes ).Invoke( null ); + property.managedReferenceValue = null; property.serializedObject.ApplyModifiedProperties(); } ); - } - menu.ShowAsContext(); + foreach( Type type in GetSubClasses( field_type ) ) + { + menu.AddItem( new GUIContent( type.Name ), type_name == type.Name, () => + { + property.managedReferenceValue = type.GetConstructor( Type.EmptyTypes ).Invoke( null ); + property.serializedObject.ApplyModifiedProperties(); + } ); + } + + menu.ShowAsContext(); + } } EditorGUI.PropertyField( position, property, label, true ); From 724c309d8610fe7697dbb2e24457f0aabce294a5 Mon Sep 17 00:00:00 2001 From: Lucas Baran Date: Fri, 18 Apr 2025 18:08:52 +0200 Subject: [PATCH 09/11] package.json: update package version from 2.3.1 to 2.3.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ef2ae7d..932232e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.fishingcactus.common-code", - "version": "2.3.1", + "version": "2.3.2", "displayName": "FC - Common Code", "description": "Code, Extensions and extra features for Fishing Cactus Games.", "unity": "2020.3", From 5347a1b041eae5f375abf7f6c589124d14780377 Mon Sep 17 00:00:00 2001 From: Lucas Baran Date: Fri, 18 Apr 2025 18:09:47 +0200 Subject: [PATCH 10/11] CHANGELOG.md: add entry for version 2.3.2 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d43cd9..a6a00b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [2.3.2] - 2025-04-18 +### Updated +- Update SubAssetPicker drawer to display mixed values and disable picker when multiple objects with different values are selected + +### Fixed +- Fix SubAssetPicker would not work with items of serialized lists and arrays +- Fix SubAssetPicker would not search for derived classes in other assemblies than the base type's assembly +- Fix tried to show the SubAssetPicker context menu as many times as there are derived types + ## [2.3.1] - 2025-04-04 ### Fixed - Path used in CreatePrefab is now relative to project folder. From 840387645d92ff7ca396567d426eeb3af360e3c2 Mon Sep 17 00:00:00 2001 From: Lucas Baran Date: Fri, 25 Apr 2025 12:43:21 +0200 Subject: [PATCH 11/11] SubClassPickerDrawer: remove debug log --- Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs index 25b5035..11f7731 100644 --- a/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs +++ b/Editor/PropertyDrawer/AttributesDrawer/SubClassPickerDrawer.cs @@ -57,7 +57,6 @@ GUIContent label { if( EditorGUI.DropdownButton( drop_down_rect, new( type_name ), FocusType.Keyboard ) ) { - Debug.Log( property.managedReferenceId ); GenericMenu menu = new GenericMenu(); menu.AddItem( new GUIContent( "None" ), property.managedReferenceValue == null, () => {