Skip to content

Instantly share code, notes, and snippets.

@EddieCameron
Last active August 7, 2023 09:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save EddieCameron/6c3d03732aecb2560cbfd9b82afe0199 to your computer and use it in GitHub Desktop.
Save EddieCameron/6c3d03732aecb2560cbfd9b82afe0199 to your computer and use it in GitHub Desktop.
ReorderableList Property Drawer
public class MyComponent : MonoBehaviour {
public LevelWaveList levelWaves;
void Start() {
DoLevelWave( levelWaves.list[0].length );
}
}
[Serializable]
public struct LevelWave {
public float length;
public GameObject[] toSpawn; // TODO patterns or something
}
[Serializable]
public class LevelWaveList : ReorderableList<LevelWave> { }
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// In Unity pre 2020, each different type you want to make a list from needs its own subclass, like UnityEvents.
/// eg :
/// [Serializable] public class IntReorderableList : ReorderableList<int> {}
[Serializable]
public class ReorderableList<T> {
public List<T> list;
}
/* ReorderableListDrawer.cs
* © Eddie Cameron 2019
* ----------------------------
*/
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
[CustomPropertyDrawer( typeof( ReorderableList<> ), useForChildren: true )]
public class ReorderableListDrawer : PropertyDrawer {
Dictionary<string, ReorderableList> _listsPerProp = new Dictionary<string, ReorderableList>();
ReorderableList GetReorderableList( SerializedProperty prop ) {
SerializedProperty listProperty = prop.FindPropertyRelative( "list" );
ReorderableList list;
if ( _listsPerProp.TryGetValue( listProperty.propertyPath, out list ) ) {
return list;
}
list = new ReorderableList( listProperty.serializedObject, listProperty, draggable: true, displayHeader: true, displayAddButton: true, displayRemoveButton: true );
_listsPerProp[listProperty.propertyPath] = list;
list.drawHeaderCallback += rect => {
EditorGUI.LabelField( rect, prop.displayName );
};
list.drawElementCallback += ( rect, index, isActive, isFocused ) => {
SerializedProperty elementProp = list.serializedProperty.GetArrayElementAtIndex( index );
if ( elementProp.hasVisibleChildren ) {
EditorGUI.PropertyField( rect, elementProp, includeChildren: true );
}
else {
EditorGUI.PropertyField( rect, elementProp, includeChildren: true, label: GUIContent.none ); // dont draw label if its a single line
}
};
list.elementHeightCallback += idx => {
SerializedProperty elementProp = listProperty.GetArrayElementAtIndex( idx );
return EditorGUI.GetPropertyHeight( elementProp );
};
return list;
}
public override void OnGUI( Rect rect, SerializedProperty serializedProperty, GUIContent label )
{
ReorderableList list = GetReorderableList( serializedProperty );
list.DoList( rect );
}
public override float GetPropertyHeight( SerializedProperty serializedProperty, GUIContent label )
{
return GetReorderableList( serializedProperty ).GetHeight();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment