Search Unity

How can I create a PropertyDrawer that renders an array of SpriteRenderers?

Discussion in 'Immediate Mode GUI (IMGUI)' started by AcademyOfFetishes, Mar 19, 2019.

  1. AcademyOfFetishes

    AcademyOfFetishes

    Joined:
    Nov 16, 2018
    Posts:
    219
    I have this class:

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. [Serializable]
    7. public class CharacterAccessory
    8. {
    9.     public string name;
    10.     public SpriteRenderer[] spriteRenderers;
    11. }
    and this drawer

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEditor;
    5. using UnityEngine;
    6.  
    7. [CustomPropertyDrawer(typeof(CharacterAccessory))]
    8. public class CharacterAccessoryDrawer : PropertyDrawer
    9. {
    10.     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    11.     {
    12.         EditorGUI.BeginProperty(position, label, property);
    13.  
    14.         var indent = EditorGUI.indentLevel;
    15.         EditorGUI.indentLevel = 1;
    16.  
    17.         var nameRect = new Rect(position.x, position.y, 175, position.height);
    18.         var spriteRenderersRect = new Rect(position.x + 180, position.y, position.width - 155, position.height);
    19.  
    20.         EditorGUI.PropertyField(nameRect, property.FindPropertyRelative("name"), GUIContent.none);
    21.         EditorGUI.PropertyField(spriteRenderersRect, property.FindPropertyRelative("spriteRenderers"));
    22.  
    23.         EditorGUI.indentLevel = indent;
    24.  
    25.         EditorGUI.EndProperty();
    26.     }
    27. }
    28.  
    29.  
    How do I get it to render the sprite renderers the way it usually does? I want it to expand and close like normal, but here's how it looks:

     
  2. AcademyOfFetishes

    AcademyOfFetishes

    Joined:
    Nov 16, 2018
    Posts:
    219
    This was the solution (note, I changed the name of the array field to "sprites"):

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5.  
    6. [CustomPropertyDrawer(typeof(CharacterAccessory))]
    7. public class CharacterAccessoryDrawer : PropertyDrawer
    8. {
    9.     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    10.     {
    11.         EditorGUI.BeginProperty(position, label, property);
    12.  
    13.         var indent = EditorGUI.indentLevel;
    14.         EditorGUI.indentLevel = 1;
    15.  
    16.         SerializedProperty nameProperty = property.FindPropertyRelative("name");
    17.         SerializedProperty spritesProperty = property.FindPropertyRelative("sprites");
    18.  
    19.         var nameRect = new Rect(position.x, position.y, 175, EditorGUI.GetPropertyHeight(nameProperty));
    20.         var spriteRenderersRect = new Rect(position.x + 180, position.y, position.width - 155, EditorGUI.GetPropertyHeight(spritesProperty));
    21.  
    22.         EditorGUI.PropertyField(nameRect, nameProperty, GUIContent.none);
    23.         EditorGUI.PropertyField(spriteRenderersRect, spritesProperty, true);
    24.  
    25.         EditorGUI.indentLevel = indent;
    26.  
    27.         EditorGUI.EndProperty();
    28.     }
    29.  
    30.     public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    31.     {
    32.         SerializedProperty nameProperty = property.FindPropertyRelative("name");
    33.         SerializedProperty spritesProperty = property.FindPropertyRelative("sprites");
    34.         float totalHeight = 0;
    35.         totalHeight += EditorGUI.GetPropertyHeight(nameProperty);
    36.         totalHeight += EditorGUI.GetPropertyHeight(spritesProperty);
    37.         return totalHeight;
    38.     }
    39.  
    40. }