Search Unity

Two PropertyDrawer for the SerializeReference, how to deal with it?

Discussion in 'Editor & General Support' started by watsonsong, Apr 28, 2021.

  1. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    I want to create an attribute support to selection implementation for SerializeReference with an interface.
    But it seems can not work with the custom drawer for the implementation class.
    Is there any way to deal with it, like the following code:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. public interface IFoo
    5. {
    6. }
    7.  
    8. public sealed class Foo : IFoo
    9. {
    10.     [SerializeField]
    11.     private int integer;
    12. }
    13.  
    14. public sealed class Bar : IFoo
    15. {
    16.     [SerializeField]
    17.     private string text;
    18.  
    19.     [SerializeField]
    20.     private float number;
    21. }
    22.  
    23. [CustomPropertyDrawer(typeof(Bar))]
    24. public sealed class BarDrawer : PropertyDrawer
    25. {
    26.     public override void OnGUI(
    27.         Rect position, SerializedProperty property, GUIContent label)
    28.     {
    29.         using var p = new EditorGUI.PropertyScope(
    30.             position, label, property);
    31.  
    32.         position.height = EditorGUIUtility.singleLineHeight;
    33.         GUI.Label(position, p.content);
    34.  
    35.         position.y += position.height;
    36.         GUI.Label(position, "Custom Bar Editor");
    37.     }
    38.  
    39.     public override float GetPropertyHeight(
    40.         SerializedProperty property, GUIContent label)
    41.     {
    42.         return 2 * EditorGUIUtility.singleLineHeight;
    43.     }
    44. }
    45.  
    46. public class SelectImplementationAttribute : PropertyAttribute
    47. {
    48. }
    49.  
    50. [CustomPropertyDrawer(typeof(SelectImplementationAttribute))]
    51. public sealed class SelectImplementationDrawer : PropertyDrawer
    52. {
    53.     public override void OnGUI(
    54.         Rect position, SerializedProperty property, GUIContent label)
    55.     {
    56.         using var p = new EditorGUI.PropertyScope(
    57.             position, label, property);
    58.         label = p.content;
    59.  
    60.         var line = position;
    61.         line.height = EditorGUIUtility.singleLineHeight;
    62.         EditorGUI.LabelField(line, label);
    63.  
    64.         line.x += EditorGUIUtility.labelWidth;
    65.         line.width -= EditorGUIUtility.labelWidth;
    66.         if (EditorGUI.DropdownButton(
    67.             line,
    68.             new GUIContent(property.managedReferenceFullTypename),
    69.             FocusType.Passive))
    70.         {
    71.             var menu = new GenericMenu();
    72.             menu.AddItem(
    73.                 new GUIContent("Foo"),
    74.                 false,
    75.                 () =>
    76.                 {
    77.                     property.serializedObject.Update();
    78.                     property.managedReferenceValue = new Foo();
    79.                     property.serializedObject.ApplyModifiedProperties();
    80.                 });
    81.             menu.AddItem(
    82.                 new GUIContent("Bar"),
    83.                 false,
    84.                 () =>
    85.                 {
    86.                     property.serializedObject.Update();
    87.                     property.managedReferenceValue = new Bar();
    88.                     property.serializedObject.ApplyModifiedProperties();
    89.                 });
    90.             menu.ShowAsContext();
    91.         }
    92.  
    93.         EditorGUI.PropertyField(position, property, GUIContent.none, true);
    94.     }
    95.  
    96.     public override float GetPropertyHeight(
    97.         SerializedProperty property, GUIContent label)
    98.     {
    99.         return EditorGUI.GetPropertyHeight(property, label, true);
    100.     }
    101. }
    102.  
    103. public sealed class DataObj : MonoBehaviour
    104. {
    105.     [SerializeReference]
    106.     [SelectImplementation]
    107.     private IFoo foo = new Bar();
    108.  
    109.     [SerializeReference]
    110.     private IFoo foo2 = new Bar();
    111. }
    112.  
    Some code has the same ability, but seems has the same question:
    https://github.com/medvedya/Select-...263e/Editor/SelectImplementationDrawer.cs#L37
    https://nigiri.hatenablog.com/entry/2021/02/04/200301
     
    Last edited: Apr 28, 2021