From 3cd27935a63c668d3e54bd5d82eb55b5481eb343 Mon Sep 17 00:00:00 2001 From: jhodk <> Date: Fri, 6 Mar 2026 23:31:29 +0000 Subject: [PATCH 1/4] fix: set label text before BeginProperty call --- Assets/Example/Example.cs | 11 ++++++++++ Assets/Example/Example.unity | 19 ++++++++++++++++++ .../Editor/SubclassSelectorDrawer.cs | 20 ++++++++++--------- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/Assets/Example/Example.cs b/Assets/Example/Example.cs index f043780..158abbf 100644 --- a/Assets/Example/Example.cs +++ b/Assets/Example/Example.cs @@ -9,6 +9,8 @@ public abstract class Food public string name; public float kcal; + + public override string ToString () => $"{name} ({kcal} kcal)"; } [Serializable] @@ -89,6 +91,15 @@ public class Example : MonoBehaviour new Peach(), new Grape() }; + + // UseToStringAsLabel support on UNITY_2021_3_OR_NEWER + [SerializeReference, SubclassSelector(UseToStringAsLabel = true)] + public List foodsThree = new List + { + new Apple(), + new Peach(), + new Grape() + }; } #if UNITY_EDITOR diff --git a/Assets/Example/Example.unity b/Assets/Example/Example.unity index 09287f1..4cb36d4 100644 --- a/Assets/Example/Example.unity +++ b/Assets/Example/Example.unity @@ -260,9 +260,28 @@ MonoBehaviour: - rid: 9020349853700980772 - rid: 9020349853700980773 - rid: 9020349853700980774 + foodsThree: + - rid: 7418200600248058228 + - rid: 7418200600248058229 + - rid: 7418200600248058230 references: version: 2 RefIds: + - rid: 7418200600248058228 + type: {class: Apple, ns: , asm: Assembly-CSharp} + data: + name: Apple + kcal: 100 + - rid: 7418200600248058229 + type: {class: Peach, ns: , asm: Assembly-CSharp} + data: + name: Peach + kcal: 100 + - rid: 7418200600248058230 + type: {class: Grape, ns: , asm: Assembly-CSharp} + data: + name: Grape + kcal: 100 - rid: 9020349853700980763 type: {class: Apple, ns: , asm: Assembly-CSharp} data: diff --git a/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs index d4b787f..6b6cc52 100644 --- a/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs +++ b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs @@ -35,20 +35,12 @@ public TypePopupCache (AdvancedTypePopup typePopup, AdvancedDropdownState state) public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { - EditorGUI.BeginProperty(position, label, property); if (property.propertyType == SerializedPropertyType.ManagedReference) { - // Render label first to avoid label overlap for lists - Rect foldoutLabelRect = new Rect(position); - foldoutLabelRect.height = EditorGUIUtility.singleLineHeight; - - // NOTE: IndentedRect should be disabled as it causes extra indentation. - //foldoutLabelRect = EditorGUI.IndentedRect(foldoutLabelRect); - Rect popupPosition = EditorGUI.PrefixLabel(foldoutLabelRect, label); - #if UNITY_2021_3_OR_NEWER // Override the label text with the ToString() of the managed reference. + // Must be called before EditorGUI.BeginProperty var subclassSelectorAttribute = (SubclassSelectorAttribute)attribute; if (subclassSelectorAttribute.UseToStringAsLabel && !property.hasMultipleDifferentValues) { @@ -59,6 +51,15 @@ public override void OnGUI (Rect position, SerializedProperty property, GUIConte } } #endif + + EditorGUI.BeginProperty(position, label, property); + // Render label first to avoid label overlap for lists + Rect foldoutLabelRect = new Rect(position); + foldoutLabelRect.height = EditorGUIUtility.singleLineHeight; + + // NOTE: IndentedRect should be disabled as it causes extra indentation. + //foldoutLabelRect = EditorGUI.IndentedRect(foldoutLabelRect); + Rect popupPosition = EditorGUI.PrefixLabel(foldoutLabelRect, label); // Draw the subclass selector popup. if (EditorGUI.DropdownButton(popupPosition, GetTypeName(property), FocusType.Keyboard)) @@ -129,6 +130,7 @@ public override void OnGUI (Rect position, SerializedProperty property, GUIConte } else { + EditorGUI.BeginProperty(position, label, property); EditorGUI.LabelField(position, label, IsNotManagedReferenceLabel); } From 2fa0a63934baf490cd91745235a1c3d50c9efb91 Mon Sep 17 00:00:00 2001 From: Makihiro <13536348+mackysoft@users.noreply.github.com> Date: Thu, 15 Oct 2026 04:38:32 +0900 Subject: [PATCH 2/4] refactor(editor): centralize subclass property drawing scope Why BeginProperty needs the prepared label and should share its drawing boundary with EndProperty. What Changed Prepare ToString labels before one common BeginProperty call, then select the managed reference or warning rendering path. Impact Preserves null, mixed value, custom drawer, and invalid property behavior while keeping the property scope in one place. --- .../Editor/SubclassSelectorDrawer.cs | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs index 6b6cc52..f1967e6 100644 --- a/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs +++ b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs @@ -35,24 +35,23 @@ public TypePopupCache (AdvancedTypePopup typePopup, AdvancedDropdownState state) public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { - - if (property.propertyType == SerializedPropertyType.ManagedReference) - { + bool isManagedReference = property.propertyType == SerializedPropertyType.ManagedReference; #if UNITY_2021_3_OR_NEWER - // Override the label text with the ToString() of the managed reference. - // Must be called before EditorGUI.BeginProperty - var subclassSelectorAttribute = (SubclassSelectorAttribute)attribute; - if (subclassSelectorAttribute.UseToStringAsLabel && !property.hasMultipleDifferentValues) + // Prepare the label before BeginProperty captures it for rendering. + if (isManagedReference && ((SubclassSelectorAttribute)attribute).UseToStringAsLabel && !property.hasMultipleDifferentValues) + { + object managedReferenceValue = property.managedReferenceValue; + if (managedReferenceValue != null) { - object managedReferenceValue = property.managedReferenceValue; - if (managedReferenceValue != null) - { - label.text = managedReferenceValue.ToString(); - } + label.text = managedReferenceValue.ToString(); } + } #endif - - EditorGUI.BeginProperty(position, label, property); + + EditorGUI.BeginProperty(position, label, property); + + if (isManagedReference) + { // Render label first to avoid label overlap for lists Rect foldoutLabelRect = new Rect(position); foldoutLabelRect.height = EditorGUIUtility.singleLineHeight; @@ -130,7 +129,6 @@ public override void OnGUI (Rect position, SerializedProperty property, GUIConte } else { - EditorGUI.BeginProperty(position, label, property); EditorGUI.LabelField(position, label, IsNotManagedReferenceLabel); } From 913194f1cedc002fd814d1359095f7ef15279030 Mon Sep 17 00:00:00 2001 From: Makihiro <13536348+mackysoft@users.noreply.github.com> Date: Thu, 15 Oct 2026 04:38:32 +0900 Subject: [PATCH 3/4] refactor(examples): keep the label demo field private Why The list is configured through the Inspector and does not need to be public. What Changed Make foodsThree private while retaining its SerializeReference and SubclassSelector attributes. Impact Keeps the existing serialized field name, scene data, and Inspector example behavior. --- Assets/Example/Example.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/Example/Example.cs b/Assets/Example/Example.cs index 158abbf..6b6455e 100644 --- a/Assets/Example/Example.cs +++ b/Assets/Example/Example.cs @@ -94,7 +94,7 @@ public class Example : MonoBehaviour // UseToStringAsLabel support on UNITY_2021_3_OR_NEWER [SerializeReference, SubclassSelector(UseToStringAsLabel = true)] - public List foodsThree = new List + private List foodsThree = new List { new Apple(), new Peach(), @@ -137,4 +137,4 @@ public override float GetPropertyHeight (SerializedProperty property, GUIContent return EditorGUIUtility.singleLineHeight; } } -#endif \ No newline at end of file +#endif From 4a256e7556a457095a3eeb80321fef647e0a0bb2 Mon Sep 17 00:00:00 2001 From: Makihiro <13536348+mackysoft@users.noreply.github.com> Date: Thu, 15 Oct 2026 04:51:40 +0900 Subject: [PATCH 4/4] style(examples): remove trailing whitespace from the label demo Why The added example should pass the complete pull request whitespace check. What Changed Remove trailing spaces from the blank line before foodsThree. Impact Changes formatting only. --- Assets/Example/Example.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Example/Example.cs b/Assets/Example/Example.cs index 6b6455e..47981e9 100644 --- a/Assets/Example/Example.cs +++ b/Assets/Example/Example.cs @@ -91,7 +91,7 @@ public class Example : MonoBehaviour new Peach(), new Grape() }; - + // UseToStringAsLabel support on UNITY_2021_3_OR_NEWER [SerializeReference, SubclassSelector(UseToStringAsLabel = true)] private List foodsThree = new List