Advertisement
zORg_alex

Generic editor for Reorderable lists

Dec 12th, 2024
88
0
Never
2
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 1.91 KB | Source Code | 0 0
  1.  
  2. #if UNITY_EDITOR
  3.  
  4.         internal virtual Rect GUIDrawElement(Rect rect, SerializedProperty serializedProperty, bool isActive, bool isFocused)
  5.         {
  6.             if (serializedProperty == null)
  7.             {
  8.                 EditorGUI.HelpBox(rect, "SerializedProperty was null!", MessageType.Error);
  9.                 return rect;
  10.             }
  11.             serializedProperty = serializedProperty.Copy();
  12.             int startingDepth = serializedProperty.depth;
  13.             var currentRect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
  14.             EditorGUI.LabelField(currentRect, serializedProperty.boxedValue.GetType().Name);
  15.             var first = true;
  16.             while (serializedProperty.NextVisible(EnterChildren(serializedProperty, first)) && serializedProperty.depth > startingDepth)
  17.             {
  18.                 first = false;
  19.                 currentRect = currentRect.MoveDownFor(EditorGUI.GetPropertyHeight(serializedProperty));
  20.                 if (serializedProperty.propertyType == SerializedPropertyType.Generic && !serializedProperty.isArray)
  21.                     currentRect = currentRect.CutFromTop(EditorGUIUtility.singleLineHeight)[0];
  22.                 EditorGUI.indentLevel = serializedProperty.depth;
  23.                 EditorGUI.PropertyField(currentRect, serializedProperty);
  24.             }
  25.             return currentRect;
  26.  
  27.             static bool EnterChildren(SerializedProperty serializedProperty, bool first)
  28.             {
  29.                 return first || (
  30.                     serializedProperty.propertyType == SerializedPropertyType.Generic
  31.                     && !serializedProperty.isArray
  32.                     && serializedProperty.isExpanded
  33.                     );
  34.             }
  35.         }
  36.  
  37.         internal virtual float GUIElementHeight(SerializedProperty serializedProperty)
  38.         {
  39.             serializedProperty = serializedProperty.Copy();
  40.             int startingDepth = serializedProperty.depth;
  41.             float height = EditorGUIUtility.singleLineHeight * 2;
  42.             var first = true;
  43.             while (serializedProperty.NextVisible(first) && serializedProperty.depth > startingDepth)
  44.             {
  45.                 first = false;
  46.                 height += EditorGUI.GetPropertyHeight(serializedProperty);
  47.             }
  48.             return height;
  49.         }
  50. #endif
Tags: unity editor
Advertisement
Comments
  • zORg_alex
    31 days
    # text 0.13 KB | 0 0
    1. I've used it to draw abstract class in ReorderableList, that can overloade this method just in case it needs some specific thing drawn.
  • zORg_alex
    31 days (edited)
    # C# 6.66 KB | 0 0
    1. TOTEST Found this on https://discussions.unity.com/t/what-is-the-best-way-to-do-a-reorderable-list/687256:
    2. using UnityEngine;
    3. using UnityEditor;
    4. using UnityEditorInternal;
    5. using System.Collections.Generic;
    6.  
    7. [CustomEditor(typeof(UnityEngine.Object), true, isFallback = true)]
    8. [CanEditMultipleObjects]
    9. public class CustomEditorBase : Editor
    10. {
    11.     private Dictionary<string, ReorderableListProperty> reorderableLists;
    12.  
    13.     protected virtual void OnEnable()
    14.     {
    15.         this.reorderableLists = new Dictionary<string, ReorderableListProperty>(10);
    16.     }
    17.  
    18.     ~CustomEditorBase()
    19.     {
    20.         this.reorderableLists.Clear();
    21.         this.reorderableLists = null;
    22.     }
    23.  
    24.     public override void OnInspectorGUI()
    25.     {
    26.         EditorGUILayout.LabelField("Custom Editor", EditorStyles.centeredGreyMiniLabel);
    27.         Color cachedGuiColor = GUI.color;
    28.         serializedObject.Update();
    29.         var property = serializedObject.GetIterator();
    30.         var next = property.NextVisible(true);
    31.         if (next)
    32.             do
    33.             {
    34.                 GUI.color = cachedGuiColor;
    35.                 this.HandleProperty(property);
    36.             } while (property.NextVisible(false));
    37.         serializedObject.ApplyModifiedProperties();
    38.     }
    39.  
    40.     protected void HandleProperty(SerializedProperty property)
    41.     {
    42.         //Debug.LogFormat("name: {0}, displayName: {1}, type: {2}, propertyType: {3}, path: {4}", property.name, property.displayName, property.type, property.propertyType, property.propertyPath);
    43.         bool isdefaultScriptProperty = property.name.Equals("m_Script") && property.type.Equals("PPtr<MonoScript>") && property.propertyType == SerializedPropertyType.ObjectReference && property.propertyPath.Equals("m_Script");
    44.         bool cachedGUIEnabled = GUI.enabled;
    45.         if (isdefaultScriptProperty)
    46.             GUI.enabled = false;
    47.         //var attr = this.GetPropertyAttributes(property);
    48.         if (property.isArray && property.propertyType != SerializedPropertyType.String)
    49.             this.HandleArray(property);
    50.         else
    51.             EditorGUILayout.PropertyField(property, property.isExpanded);
    52.         if (isdefaultScriptProperty)
    53.             GUI.enabled = cachedGUIEnabled;
    54.     }
    55.  
    56.     protected void HandleArray(SerializedProperty property)
    57.     {
    58.         var listData = this.GetReorderableList(property);
    59. //        if (!property.isExpanded)
    60. //        {
    61. //            EditorGUILayout.BeginHorizontal(EditorStyles.foldout);
    62. //            property.isExpanded = EditorGUILayout.ToggleLeft(string.Format("{0}[]", property.displayName), property.isExpanded, EditorStyles.boldLabel);
    63. //            EditorGUILayout.LabelField(string.Format("size: {0}", property.arraySize));
    64. //            EditorGUILayout.EndHorizontal();
    65. //        }
    66. //        else {
    67.             listData.List.DoLayoutList();
    68. //        }
    69.     }
    70.  
    71.     protected object[] GetPropertyAttributes(SerializedProperty property)
    72.     {
    73.         return this.GetPropertyAttributes<PropertyAttribute>(property);
    74.     }
    75.  
    76.     protected object[] GetPropertyAttributes<T>(SerializedProperty property) where T : System.Attribute
    77.     {
    78.         System.Reflection.BindingFlags bindingFlags = System.Reflection.BindingFlags.GetField
    79.             | System.Reflection.BindingFlags.GetProperty
    80.             | System.Reflection.BindingFlags.IgnoreCase
    81.             | System.Reflection.BindingFlags.Instance
    82.             | System.Reflection.BindingFlags.NonPublic
    83.             | System.Reflection.BindingFlags.Public;
    84.         if (property.serializedObject.targetObject == null)
    85.             return null;
    86.         var targetType = property.serializedObject.targetObject.GetType();
    87.         var field = targetType.GetField(property.name, bindingFlags);
    88.         if (field != null)
    89.             return field.GetCustomAttributes(typeof(T), true);
    90.         return null;
    91.     }
    92.  
    93.     private ReorderableListProperty GetReorderableList(SerializedProperty property)
    94.     {
    95.         ReorderableListProperty ret = null;
    96.         if (this.reorderableLists.TryGetValue(property.name, out ret))
    97.         {
    98.             ret.Property = property;
    99.             return ret;
    100.         }
    101.         ret = new ReorderableListProperty(property);
    102.         this.reorderableLists.Add(property.name, ret);
    103.         return ret;
    104.     }
    105.  
    106.     #region Inner-class ReorderableListProperty
    107.     private class ReorderableListProperty
    108.     {
    109.         /// <summary>
    110.         /// ref http://va.lent.in/unity-make-your-lists-functional-with-reorderablelist/
    111.         /// </summary>
    112.         public ReorderableList List { get; private set; }
    113.  
    114.         private SerializedProperty _property;
    115.         public SerializedProperty Property
    116.         {
    117.             get { return this._property; }
    118.             set
    119.             {
    120.                 this._property = value;
    121.                 this.List.serializedProperty = this._property;
    122.             }
    123.         }
    124.  
    125.         public ReorderableListProperty(SerializedProperty property)
    126.         {
    127.             this._property = property;
    128.             this.CreateList();
    129.         }
    130.  
    131.         ~ReorderableListProperty()
    132.         {
    133.             this._property = null;
    134.             this.List = null;
    135.         }
    136.  
    137.         private void CreateList()
    138.         {
    139.             bool dragable = true, header = true, add = true, remove = true;
    140.             this.List = new ReorderableList(this.Property.serializedObject, this.Property, dragable, header, add, remove);
    141.             this.List.drawHeaderCallback += rect => EditorGUI.LabelField (rect, this._property.displayName);// EditorGUI.ToggleLeft(rect, this._property.displayName, this._property.isExpanded, EditorStyles.boldLabel);
    142.             this.List.onCanRemoveCallback += (list) => { return this.List.count > 0; };
    143.             this.List.drawElementCallback += this.drawElement;
    144.             this.List.elementHeightCallback += (idx) => { return Mathf.Max(EditorGUIUtility.singleLineHeight, EditorGUI.GetPropertyHeight(this._property.GetArrayElementAtIndex(idx), GUIContent.none, true)) + 4.0f; };
    145.         }
    146.  
    147.         private void drawElement(Rect rect, int index, bool active, bool focused)
    148.         {
    149.             if (this._property.GetArrayElementAtIndex(index).propertyType == SerializedPropertyType.Generic)
    150.             {
    151.                 EditorGUI.LabelField(rect, this._property.GetArrayElementAtIndex(index).displayName);
    152.             }
    153.             //rect.height = 16;
    154.             rect.height = EditorGUI.GetPropertyHeight(this._property.GetArrayElementAtIndex(index), GUIContent.none, true);
    155.             rect.y += 1;
    156.             EditorGUI.PropertyField(rect, this._property.GetArrayElementAtIndex(index), GUIContent.none, true);
    157.             this.List.elementHeight = rect.height + 4.0f;
    158.         }
    159.     }
    160.     #endregion
    161. }
    162.  
Add Comment
Please, Sign In to add comment
Advertisement