unity3d-reorderable-list
unity3d-reorderable-list copied to clipboard
Reordable lists of custom serializable object don't respect item size
Hi,
I was trying to use your plugin to show some Serializable
item, but the height of the displayed list item doesn't respect the item.
And this is the simple code to generate this.
WordPicker.cs
[CreateAssetMenu(fileName = "WordPicker", menuName = "Quest/WordPicker", order = 3)]
public class WordPicker : ScriptableObject
{
[System.Serializable]
public class Choice
{
[Tooltip("Possible valid words/senteces, separated by commas ','")]
public string valids;
[Tooltip("Possible invalid words/strings, separated by commas ','")]
public string invalids;
}
[TextArea(3, 10)]
public string phrase;
[Tooltip("List of valid and invlid words/strings")]
public List<Choice> choices;
}
WordPickerEditor.cs
[CustomPropertyDrawer(typeof(WordPicker.Choice))]
public class Drawer : PropertyDrawer
{
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
EditorGUI.BeginProperty(position, label, property);
// Draw label
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
// Don't make child fields be indented
var indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
// Draw fields - passs GUIContent.none to each so they are drawn without labels
Rect validPos = position;
var validProp = property.FindPropertyRelative("valids");
var validLabel = new GUIContent("Valid words");
EditorGUI.PropertyField(validPos, validProp, validLabel);
float validHeight = EditorGUI.GetPropertyHeight(validProp, validLabel, true);
Rect invalidPos = validPos;
invalidPos.y += validHeight;
EditorGUI.PropertyField(invalidPos, property.FindPropertyRelative("invalids"), new GUIContent("Invalid words"));
// Set indent back to what it was
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty();
}
}
//[CanEditMultipleObjects]
[CustomEditor(typeof(WordPicker))]
public class WordPickerEditor : UnityEditor.Editor
{
private SerializedProperty _phraseProperty;
private SerializedProperty _listProperty;
private ReorderableListControl _listControl;
private IReorderableListAdaptor _listAdaptor;
private void OnEnable()
{
_phraseProperty = serializedObject.FindProperty("phrase");
_listControl = new ReorderableListControl();
_listProperty = serializedObject.FindProperty("choices");
_listAdaptor = new SerializedPropertyAdaptor(_listProperty);
}
public override void OnInspectorGUI()
{
serializedObject.Update();
_listControl.Draw(_listAdaptor);
serializedObject.ApplyModifiedProperties();
}
}
Even if I try to set the list item height manually e.g. ReorderableListGUI.ListField(_listProperty, 36f);
(not desired anyway), the first item will be stretched to cover the whole height, overlapping the second.
What am I doing wrong?
Once we are here, I have tried to use ReorderableListAttribute
with no luck, I couldn't find the way of using this. Would you mind to provide a simple example? Maybe to apply in this case, as far as I understand this can potentially reduce the amount of code I need to write to make the reordable-list work nicely.
Thanks, Fabio
The issue is inside your custom property drawer. Unity provides two methods that should be overridden; GetPropertyHeight and OnGUI.
So in your case, something like this (not tested):
[CustomPropertyDrawer(typeof(WordPicker.Choice))]
public class Drawer : PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
var validProp = property.FindPropertyRelative("valids");
var invalidProp = property.FindPropertyRelative("invalids");
return EditorGUI.GetPropertyHeight(validProp, GUIContent.none, true)
+ EditorGUI.GetPropertyHeight(invalidProp , GUIContent.none, true);
}
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
EditorGUI.BeginProperty(position, label, property);
// Draw label
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
// Don't make child fields be indented
var indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
// Draw fields - passs GUIContent.none to each so they are drawn without labels
Rect validPos = position;
var validProp = property.FindPropertyRelative("valids");
var validLabel = new GUIContent("Valid words");
EditorGUI.PropertyField(validPos, validProp, validLabel);
float validHeight = EditorGUI.GetPropertyHeight(validProp, validLabel, true);
Rect invalidPos = validPos;
invalidPos.y += validHeight;
EditorGUI.PropertyField(invalidPos, property.FindPropertyRelative("invalids"), new GUIContent("Invalid words"));
// Set indent back to what it was
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty();
}
}