diff --git a/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/ManagedReferenceUtility.cs b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/ManagedReferenceUtility.cs index 577efde..0d84906 100644 --- a/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/ManagedReferenceUtility.cs +++ b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/ManagedReferenceUtility.cs @@ -4,7 +4,9 @@ using UnityEditor; using UnityEngine; -namespace MackySoft.SerializeReferenceExtensions.Editor { +namespace MackySoft.SerializeReferenceExtensions.Editor +{ + public static class ManagedReferenceUtility { public static object SetManagedReference (this SerializedProperty property,Type type) { @@ -12,7 +14,7 @@ public static class ManagedReferenceUtility { #if UNITY_2021_3_OR_NEWER // NOTE: managedReferenceValue getter is available only in Unity 2021.3 or later. - if (property.managedReferenceValue != null && type != null) + if ((type != null) && (property.managedReferenceValue != null)) { // Restore an previous values from json. string json = JsonUtility.ToJson(property.managedReferenceValue); diff --git a/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SerializedPropertyExtensions.cs b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SerializedPropertyExtensions.cs new file mode 100644 index 0000000..135fe25 --- /dev/null +++ b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SerializedPropertyExtensions.cs @@ -0,0 +1,31 @@ +#if UNITY_2019_3_OR_NEWER +using System.Collections.Generic; +using UnityEditor; + +namespace MackySoft.SerializeReferenceExtensions.Editor +{ + public static class SerializedPropertyExtensions + { + public static IEnumerable GetChildProperties (this SerializedProperty parent, int depth = 1) + { + parent = parent.Copy(); + + int depthOfParent = parent.depth; + var enumerator = parent.GetEnumerator(); + + while (enumerator.MoveNext()) + { + if (enumerator.Current is not SerializedProperty childProperty) + { + continue; + } + if (childProperty.depth > (depthOfParent + depth)) + { + continue; + } + yield return childProperty.Copy(); + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SerializedPropertyExtensions.cs.meta b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SerializedPropertyExtensions.cs.meta new file mode 100644 index 0000000..0491dc7 --- /dev/null +++ b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SerializedPropertyExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b934aeca38cb7a24cabd6047fe0e298a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs index 0bfe2be..1522679 100644 --- a/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs +++ b/Assets/MackySoft/MackySoft.SerializeReferenceExtensions/Editor/SubclassSelectorDrawer.cs @@ -31,51 +31,74 @@ struct TypePopupCache { SerializedProperty m_TargetProperty; - public override void OnGUI (Rect position,SerializedProperty property,GUIContent label) { - EditorGUI.BeginProperty(position,label,property); - - if (property.propertyType == SerializedPropertyType.ManagedReference) { + public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) + { + EditorGUI.BeginProperty(position, label, property); - // render label first to avoid label overlap for lists + if (property.propertyType == SerializedPropertyType.ManagedReference) + { + // Render label first to avoid label overlap for lists Rect foldoutLabelRect = new Rect(position); foldoutLabelRect.height = EditorGUIUtility.singleLineHeight; - foldoutLabelRect.x += EditorGUI.indentLevel * 12; + foldoutLabelRect = EditorGUI.IndentedRect(foldoutLabelRect); Rect popupPosition = EditorGUI.PrefixLabel(foldoutLabelRect, label); // Draw the subclass selector popup. - if (EditorGUI.DropdownButton(popupPosition,GetTypeName(property),FocusType.Keyboard)) { + if (EditorGUI.DropdownButton(popupPosition, GetTypeName(property), FocusType.Keyboard)) + { TypePopupCache popup = GetTypePopup(property); m_TargetProperty = property; popup.TypePopup.Show(popupPosition); } - // Check if a custom property drawer exists for this type. - PropertyDrawer customDrawer = GetCustomPropertyDrawer(property); - if (customDrawer != null) + // Draw the foldout. + if (!string.IsNullOrEmpty(property.managedReferenceFullTypename)) { - // Draw the property with custom property drawer. Rect foldoutRect = new Rect(position); foldoutRect.height = EditorGUIUtility.singleLineHeight; + foldoutRect.x -= 12; property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, GUIContent.none, true); + } - if (property.isExpanded) + // Draw property if expanded. + if (property.isExpanded) + { + using (new EditorGUI.IndentLevelScope()) { - using (new EditorGUI.IndentLevelScope()) + // Check if a custom property drawer exists for this type. + PropertyDrawer customDrawer = GetCustomPropertyDrawer(property); + if (customDrawer != null) { + // Draw the property with custom property drawer. Rect indentedRect = position; float foldoutDifference = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; indentedRect.height = customDrawer.GetPropertyHeight(property, label); indentedRect.y += foldoutDifference; customDrawer.OnGUI(indentedRect, property, label); } + else + { + // Draw the properties of the child elements. + // NOTE: In the following code, since the foldout layout isn't working properly, I'll iterate through the properties of the child elements myself. + // EditorGUI.PropertyField(position, property, GUIContent.none, true); + + Rect childPosition = position; + childPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + foreach (SerializedProperty childProperty in property.GetChildProperties()) + { + float height = EditorGUI.GetPropertyHeight(childProperty, new GUIContent(childProperty.displayName, childProperty.tooltip), true); + childPosition.height = height; + EditorGUI.PropertyField(childPosition, childProperty, true); + + childPosition.y += height + EditorGUIUtility.standardVerticalSpacing; + } + } } } - else - { - EditorGUI.PropertyField(position, property, GUIContent.none, true); - } - } else { - EditorGUI.LabelField(position,label,k_IsNotManagedReferenceLabel); + } + else + { + EditorGUI.LabelField(position, label, k_IsNotManagedReferenceLabel); } EditorGUI.EndProperty(); @@ -117,7 +140,6 @@ PropertyDrawer GetCustomPropertyDrawer (SerializedProperty property) foreach (var targetObject in m_TargetProperty.serializedObject.targetObjects) { SerializedObject individualObject = new SerializedObject(targetObject); SerializedProperty individualProperty = individualObject.FindProperty(m_TargetProperty.propertyPath); - object obj = individualProperty.SetManagedReference(type); individualProperty.isExpanded = (obj != null);