Search Unity

Unity 4.5 ReorderableList

Discussion in 'Scripting' started by PrefabEvolution, Jun 1, 2014.

  1. PrefabEvolution

    PrefabEvolution

    Joined:
    Mar 27, 2014
    Posts:
    225
    Today i have find new non documented Unity 4.5 Feature. Its native UnityEditorInternal.ReorderableList!
    $Screen Shot 2014-06-01 at 16.19.57.png
    Its very easy way to add more convenient behavior of array properties inside your Editor GUI with or without GUILayout.

    Its very simple:
    Code (csharp):
    1.  
    2. var reorderableList = new UnityEditorInternal.ReorderableList(List<SomeType> someList, typeof(SomeType), dragable, displayHeader, displayAddButton, displayRemoveButton);
    3. reorderableList.DoList(rect);
    4. //or
    5. reorderableList.DoLayoutList()
    6.  
    Previously i am looking for native reorderable list inside unity, but it was have only internal access and there is no way(simple way) to add it to my own GUI
     
    Last edited: Jun 1, 2014
  2. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Cool, but I understand you still have to write a custom editor to have your collection show up like that?
     
  3. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    A custom property drawer would be convenient.
     
    lermy3d likes this.
  4. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Can you do one for all collection type? Like... IList or ICollection or something?
     
  5. PrefabEvolution

    PrefabEvolution

    Joined:
    Mar 27, 2014
    Posts:
    225
    There is no simple way to make this work without Custom Editor.
    Probably it not good enough, but simple...:
    Code (csharp):
    1.  
    2. using UnityEngine;using System.Collections.Generic;
    3.  
    4.  
    5. [System.Serializable]
    6. public class ReorderableList_Vector3 : ReorderableList<Vector3>{}
    7. [System.Serializable]
    8. public class ReorderableList_RectOffset : ReorderableList<RectOffset>{}
    9. public class ReorderableList<T> : SimpleReorderableList
    10. {
    11.     public List<T> List;
    12. }
    13.  
    14.  
    15. public class SimpleReorderableList{}
    16. #if UNITY_EDITOR
    17. [CustomPropertyDrawer(typeof(SimpleReorderableList), true)]
    18. public class ReorderableListDrawer :  UnityEditor.PropertyDrawer
    19. {
    20.     private UnityEditorInternal.ReorderableList list;
    21.  
    22.  
    23.     private UnityEditorInternal.ReorderableList getList(SerializedProperty property)
    24.     {
    25.         if (list == null)
    26.         {
    27.             list = new ReorderableList(property.serializedObject, property, true, true, true, true);
    28.             list.drawElementCallback = (UnityEngine.Rect rect, int index, bool isActive, bool isFocused) =>
    29.             {
    30.                 rect.width -= 40;
    31.                 rect.x += 20;
    32.                 EditorGUI.PropertyField(rect, property.GetArrayElementAtIndex(index), true);
    33.             };
    34.         }
    35.         return list;
    36.     }
    37.  
    38.  
    39.     public override float GetPropertyHeight(SerializedProperty property, UnityEngine.GUIContent label)
    40.     {
    41.         return getList(property.FindPropertyRelative("List")).GetHeight();
    42.     }
    43.  
    44.  
    45.     public override void OnGUI(UnityEngine.Rect position, SerializedProperty property, UnityEngine.GUIContent label)
    46.     {
    47.         var listProperty = property.FindPropertyRelative("List");
    48.         var list = getList(listProperty);
    49.         var height = 0f;
    50.         for(var i = 0; i < listProperty.arraySize; i++)
    51.         {
    52.             height = Mathf.Max(height, EditorGUI.GetPropertyHeight(listProperty.GetArrayElementAtIndex(i)));
    53.         }
    54.         list.elementHeight = height;
    55.         list.DoList(position);
    56.     }
    57. }
    58. #endif
    59.  
    60.  
    61.  
     
    lermy3d likes this.
  6. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Yiakes... Alright, not implementing that in my package right now. I'll stick with my own sortable collection until Unity find a way to apply it to all collection without any custom editor or property drawer.
     
  7. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    I'm currently using a custom property drawer for generic list elements, which means that it works on a per-field basis, using a custom attribute. Unfortunately I had to use some hacks to make it work (Some reflection and some string parsing), so it doesn't respond well to adding the attribute to other types of fields. But it works.

    Here's how I'm using it:
    Code (csharp):
    1. [ReorderableList][SerializeField] protected List<SimulationStep> m_steps = new List<SimulationStep>();
    So it shouldn't have to require a very significant code change when Unity finally makes their built-in reorderable list available.
     
    Last edited: Jun 1, 2014
  8. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    list.elementHeight = height;

    is there no way to set the height of the elements individually?
    they all have to be the same size as the most expanded one!?
    thanks
     
  9. PrefabEvolution

    PrefabEvolution

    Joined:
    Mar 27, 2014
    Posts:
    225
    Unfortunate, but native ReorderableList doesn't provide this feature.
     
  10. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Well, for what it is worth, my "Advanced Inspector" package allows every items to be of different size, or even have an expansion arrow on the left.
     
  11. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    ya wow that looks great! thanks
     
  12. Essential

    Essential

    Joined:
    Sep 8, 2011
    Posts:
    265
    I noticed some of you guys mentioning the element height — is there some way to change the height of the elements shown in the ReorderableList? I don't care if they're all the same size, but I need each element taller than a single line.

    // Edit: Ah, I figured it out based on @PrefabEvolution's code sample :)
     
    Last edited: Jul 4, 2014
  13. BenbowMAS

    BenbowMAS

    Joined:
    Jul 16, 2013
    Posts:
    13
    Hey everybody, i'm actually searching a way for unselect the list programatically ... any idea ?? the idea is to lose the focus or/and the "isActive" ... thank you !
     
  14. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    Code (CSharp):
    1. Selection.activeObject = null;
    maybe
     
  15. BenbowMAS

    BenbowMAS

    Joined:
    Jul 16, 2013
    Posts:
    13
    Good try ... but it unselect my asset in the project panel and undisplay the inspector panel. My goal is to unselect a field on the inspector panel, without undisplaying it... or find a way to unselect only a field of a reordable list, or even, maybe, find a way to trigger the "select" event on a field already selected ...
     
  16. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Have you tried;

    Code (csharp):
    1. GUIUtility.hotControl = 0;
     
    IvanAuda likes this.
  17. mtalbott

    mtalbott

    Joined:
    Dec 21, 2011
    Posts:
    125
    @PrefabEvolution

    Thank you for sharing what you've found.

    In the image you included in the original post, your header is shown with a foldout label and without the default ReorderableList Header GUIStyle. Can you share how you accomplished this? I have tried to mess with drawHeaderCallback but I can't seem to change the style of the header.

    PS. anyone who wants to know more about ReorderableList, check this blog post out:
    http://va.lent.in/unity-make-your-lists-functional-with-reorderablelist/
     
    lermy3d and RC-1290 like this.
  18. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    953
    I created a custom reorderable list field prior to the Unity one being exposed which is open source and can be downloaded from the following Git repository:

    https://bitbucket.org/rotorz/reorderable-list-editor-field-for-unity

    I use my control a LOT; perhaps others here will find it useful in their projects. I haven't use the non-documented Unity control, but looking at the IntelliSense popup it seems to work in a different way.
    This can be achieved with my control!


    http://rotorz.bitbucket.org/reorder...html/2f23ba64-dea5-40d7-ae67-6a9822fd278d.htm

    I'd love to know what people think of my control :)
     
    lermy3d and Essential like this.
  19. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Does it support dynamic size? Like... If I don't know the size of an item and it's drawn using Layout?
     
  20. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    953
    Whilst the control can itself be drawn with layout or absolute position, list items are drawn using absolute position.

    You can calculate the height of your list items in 'real time' by calculating layout height inside the GetItemHeight function of a custom adaptor. With that you could probably use GUIStyle.CalcHeight.
     
  21. cmcpasserby

    cmcpasserby

    Joined:
    Jul 18, 2014
    Posts:
    315
    ya when using this i had to calculate the width in realtime and use that to size my elements in the list, in my case it was actually preferable, since im using the ReorderableList to display a list<> of my own custom Object type, and i have the ReorderableList displaying multiple attributes of that custom dataytype in one line.
     
  22. mtalbott

    mtalbott

    Joined:
    Dec 21, 2011
    Posts:
    125
    @numberkruncher. I have looked at and tested your custom Reorderable List before and I think it is very well done. Thank you for sharing it with the community.

    For the moment, I'm going to stick with the Built-in ReorderableList because of two desired features: having a persistent selected item, and having a drop-down menu on clicking the add button for polymorphic lists. That said, I do really like the right-click context menu your solution provides.

    If Unity rejects my Asset for the Asset Store because it uses undocumented api, then I'll be switching to your system for sure.
     
  23. dorpeleg

    dorpeleg

    Joined:
    Aug 20, 2011
    Posts:
    250
  24. dorpeleg

    dorpeleg

    Joined:
    Aug 20, 2011
    Posts:
    250
    Nvm, Just saw it now, not sure how I missed it