うにてぃブログ

UnityやUnreal Engineの記事を書いていきます

【Unity】UnityEditor で IList の表示に ReorderableList を使う

Inspector

Inspector で ReorderableList を利用する場合は
SerializedObjectSerializedProperty が利用できるので結構簡単にReorderableListが利用できる

f:id:hacchi_man:20200226215542p:plain:w400

クラスを List の型に指定してしまうとちょっと見た目が悪くなってしまうので 見栄えをよくするならちゃんとクラスの中身だけを表示するようにしたほうがいいかも

using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

public class SampleMonoBehaviour : MonoBehaviour
{
    [Serializable]
    public class SampleClass
    {
        public string SampleString;
        public int SampleInt;
    }
    
    [SerializeField]
    private List<SampleClass> _list;
}

[CustomEditor(typeof(SampleMonoBehaviour))]
public class SampleMonoBehaviourEditor : Editor
{
    private ReorderableList _reorderableList;
    
    private void OnEnable()
    {
        var _list = serializedObject.FindProperty("_list");
        _reorderableList = new ReorderableList(serializedObject, _list)
        {
            drawElementCallback = (rect, index, active, focused) =>
            {
                rect.xMin += 10;
                EditorGUI.PropertyField(rect, _list.GetArrayElementAtIndex(index), true);
            },
            elementHeightCallback = index => EditorGUI.GetPropertyHeight(_list.GetArrayElementAtIndex(index)),
        };
    }
    
    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        _reorderableList.DoLayoutList();
        serializedObject.ApplyModifiedProperties();
    }
}

EditorWindow

Inspector で ReorderableList を利用する場合は、クラスのインスタンス作成時に List を一緒に渡す必要がある
また、要素も Rect を駆使して作成する必要があるため結構手間になる

f:id:hacchi_man:20200226223953p:plain:w400

using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

public class SampleEditor : EditorWindow
{
    private ReorderableList _reorderableList;
    
    [Serializable]
    public class SampleClass
    {
        public string SampleString;
        public int SampleInt;
    }
    
    [SerializeField]
    private List<SampleClass> _list;
    
    private void OnEnable()
    {
        if (_list == null)
            _list = new List<SampleClass>();
        
        _reorderableList = new ReorderableList(_list, typeof(SampleClass))
        {
            drawHeaderCallback = rect => 
            {
                EditorGUI.LabelField(rect, "SampleClass");
            },
            drawElementCallback = (rect, index, active, focused) =>
            {
                rect.height = EditorGUIUtility.singleLineHeight;
                rect = EditorGUI.PrefixLabel(rect, new GUIContent("Element " + index));
                _list[index].SampleString = EditorGUI.TextField(rect, _list[index].SampleString);
                rect.y += rect.height; 
                _list[index].SampleInt = EditorGUI.IntField(rect, _list[index].SampleInt);
            },
            elementHeightCallback = index => EditorGUIUtility.singleLineHeight * 2,
        };
    }

    private void OnGUI()
    {
        _reorderableList.DoLayoutList();
    }
}