Unity 4.5 ReorderableList

Today i have find new non documented Unity 4.5 Feature. Its native UnityEditorInternal.ReorderableList!
1648549--102781--$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:

var reorderableList = new UnityEditorInternal.ReorderableList(List<SomeType> someList, typeof(SomeType), dragable, displayHeader, displayAddButton, displayRemoveButton);
reorderableList.DoList(rect);
//or
reorderableList.DoLayoutList()

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

Cool, but I understand you still have to write a custom editor to have your collection show up like that?

A custom property drawer would be convenient.

1 Like

Can you do one for all collection type? Like… IList or ICollection or something?

There is no simple way to make this work without Custom Editor.
Probably it not good enough, but simple…:

using UnityEngine;using System.Collections.Generic;


[System.Serializable]
public class ReorderableList_Vector3 : ReorderableList<Vector3>{}
[System.Serializable]
public class ReorderableList_RectOffset : ReorderableList<RectOffset>{}
public class ReorderableList<T> : SimpleReorderableList
{
	public List<T> List;
}


public class SimpleReorderableList{}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(SimpleReorderableList), true)]
public class ReorderableListDrawer :  UnityEditor.PropertyDrawer
{
	private UnityEditorInternal.ReorderableList list;


	private UnityEditorInternal.ReorderableList getList(SerializedProperty property)
	{
		if (list == null)
		{
			list = new ReorderableList(property.serializedObject, property, true, true, true, true);
			list.drawElementCallback = (UnityEngine.Rect rect, int index, bool isActive, bool isFocused) =>
			{
				rect.width -= 40;
				rect.x += 20;
				EditorGUI.PropertyField(rect, property.GetArrayElementAtIndex(index), true);
			};
		}
		return list;
	}


	public override float GetPropertyHeight(SerializedProperty property, UnityEngine.GUIContent label)
	{
		return getList(property.FindPropertyRelative("List")).GetHeight();
	}


	public override void OnGUI(UnityEngine.Rect position, SerializedProperty property, UnityEngine.GUIContent label)
	{
		var listProperty = property.FindPropertyRelative("List");
		var list = getList(listProperty);
		var height = 0f;
		for(var i = 0; i < listProperty.arraySize; i++)
		{
			height = Mathf.Max(height, EditorGUI.GetPropertyHeight(listProperty.GetArrayElementAtIndex(i)));
		}
		list.elementHeight = height;
		list.DoList(position);
	}
}
#endif
1 Like

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.

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:

[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.

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

Unfortunate, but native ReorderableList doesn’t provide this feature.

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.

ya wow that looks great! thanks

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 :slight_smile:

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 !

Selection.activeObject = null;

maybe

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 …

Have you tried;

GUIUtility.hotControl = 0;
1 Like

@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:

2 Likes

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!

I’d love to know what people think of my control :slight_smile:

2 Likes

Does it support dynamic size? Like… If I don’t know the size of an item and it’s drawn using Layout?

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.