Hello Unity peeps,
I’ve been mashing up a new ReorderableList based off of the undocumented UnityEngineInternal (using Unity 5.1.1f1) one. It’s operational, but still a work in progress - so backup your projects please.
Huge credit to CDF for his implementation which helped fix several issues and add new features.
Currently supports
-
No need to define a CustomEditor or CustomPropertyDrawer.
-
Drag and drop reordering.
-
Multiple selection (ctrl/command to toggle, shift to select range).
-
Collapsible list and child elements (shift-click to expand/collapse all child elements).
-
Variable element heights.
-
Add, and delete selection.
-
Helper method to transfer data serialized from regular lists/arrays into ReorderableLists.
Current downsides
- The need to subclass a new list for every type you need. The biggest downside, but necessary due to Unity’s design which doesn’t play nice with generic/polymorphic types, and because they insist on handling lists their own way - locking out access any other way. I’ve alleviated the burden as much as possible by providing my ReorderableList.OfType definition to derive from, which implements the same interfaces and methods as a regular List (in fact it just forwards all calls to an internal List), as well as added an implicit operator to convert to List when needed. It ends up needing little more than one line for each new type of list, and I’ve added definitions for common ones already.
- Some reflection to access internal editor functionality. Though bound to add a performance overhead, I haven’t noticed a difference. But more importantly this introduces dependencies on undocumented Unity internals which are vulnerable to breaking changes on Unity updates.
- Uses a default CustomEditor to draw all components that do not have their own CustomEditor defined. Necessary for a strange and mysterious reason which would otherwise result in a graphical glitch when dragging elements. No idea.
- Removed list editor callbacks. To make it easier on me and because I didn’t care to keep them around (in case anyone knows what I’m talking about, otherwise ignore). Could be added back in with a little bit of work if somebody really wants them back.
Those are all the points I can think of for now. It’s late. Sleep is imminent.
Usage
Simply use one of the supplied list classes (ListOfString, ListOfVector3, or define your own), et voila. Everything else should be automagically taken care of.
Defining Custom Lists
Just follow the pattern, passing in your own Serializable type as the generic parameter (here Custom):
using Assets.ReorderableList;
[Serializable]
public class ListOfCustom : ReorderableList.Of<Custom> { }
Converting Old Lists
To transfer existing data from regular lists to new fancy-pants lists you can use my supplied helper shtuff with some serialization callback logic like so:
using System.Collections.Generic;
using Assets.ReorderableList;
using Assets.ReorderableList.Helpers;
using UnityEngine;
public class MyComponent : MonoBehaviour, ISerializationCallbackReceiver
{
public List<string> MyStrings;
[TransferList("MyStrings")]
public ListOfString MyNewStrings;
void ISerializationCallbackReceiver.OnBeforeSerialize() { }
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
ListSerializationHelper.TransferLists(this);
}
}
And the next time the scene gets deserialized, your new list will be populated with elements of the old. Then you should remove the serialization callback and TransferList nonsense and rename your new list if you’d like (make sure you use Unity’s FormerlySerializedAs attribute to preserve the values if you do). You’ll most likely need to do this for each scene in your project.
That’s it for now, hope it’s useful to someone. Post with fixes/suggestions/feedback if you’d like.
Good coding!
2273775–206586–Roland1234 ReorderableLists.unitypackage (19.3 KB)