クラスの IList を UnityEditor 上に表示させるときに
縦並びよりは横並びの方が見やすいのではないかと思ったので作成してみた
表示の調整のために Rect をいじっているため結構読みにくいです
using UnityEditor; using UnityEngine; public static class ListHorizontal { private static readonly Dictionary<string, Vector2> _scrollPositionDic = new Dictionary<string, Vector2>(); public static void Draw(SerializedProperty self, float labelWidth = 80f, float fieldWidth = 150f) { if (!self.isArray || self.propertyType == SerializedPropertyType.String) { EditorGUILayout.PropertyField(self, new GUIContent(self.displayName), true); return; } if (!_scrollPositionDic.ContainsKey(self.propertyPath)) _scrollPositionDic.Add(self.propertyPath, Vector2.zero); var buttonWidth = 20f; var scrollbarHeight = 14f; // スクロール分を確保 var height = EditorGUIUtility.singleLineHeight + scrollbarHeight; if (self.arraySize > 0) { var iterator = self.GetArrayElementAtIndex(0).Copy(); var depth = iterator.depth; for (var enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false) { if (iterator.depth <= depth) continue; height += EditorGUI.GetPropertyHeight(iterator); } } var scrollRect = EditorGUILayout.GetControlRect(false, height); height -= scrollbarHeight; var viewRect = new Rect(scrollRect.x, scrollRect.y, labelWidth, height); using (new GUI.GroupScope(viewRect, GUI.skin.box)) { viewRect.x = viewRect.y = 0; viewRect.xMin += 5; { viewRect.height = EditorGUIUtility.singleLineHeight; viewRect.width -= buttonWidth; EditorGUI.LabelField(viewRect, self.displayName); viewRect.x += viewRect.width; viewRect.width = buttonWidth; if (GUI.Button(viewRect, "+")) self.InsertArrayElementAtIndex(self.arraySize); } viewRect.x = 0; if (self.arraySize > 0) { viewRect.width = labelWidth; viewRect.xMin += 10; var iterator = self.GetArrayElementAtIndex(0).Copy(); var depth = iterator.depth; for (var enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false) { if (iterator.depth <= depth) continue; viewRect.y += viewRect.height; EditorGUI.LabelField(viewRect, iterator.displayName); } } } scrollRect.width -= labelWidth; scrollRect.x += labelWidth; viewRect.x = viewRect.y = 0; viewRect.width = fieldWidth * self.arraySize; viewRect.height = height; using (var scroll = new GUI.ScrollViewScope(scrollRect, _scrollPositionDic[self.propertyPath], viewRect)) { _scrollPositionDic[self.propertyPath] = scroll.scrollPosition; viewRect.width = fieldWidth * self.arraySize; viewRect.height = height; using (new GUI.GroupScope(viewRect)) { for (var i = 0; i < self.arraySize; i++) { viewRect.x = i * fieldWidth; viewRect.y = 0f; viewRect.width = fieldWidth; viewRect.height = height; using (new GUI.GroupScope(viewRect, GUI.skin.box)) { viewRect.x = 0f; viewRect.height = EditorGUIUtility.singleLineHeight; { viewRect.width -= buttonWidth; viewRect.xMin += 5; EditorGUI.LabelField(viewRect, i.ToString()); viewRect.x += viewRect.width; viewRect.width = buttonWidth; if (GUI.Button(viewRect, "-")) { self.DeleteArrayElementAtIndex(i); return; } } viewRect.x = 0f; viewRect.width = fieldWidth; var iterator = self.GetArrayElementAtIndex(i).Copy(); var depth = iterator.depth; for (var enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false) { if (iterator.depth <= depth) continue; viewRect.y += viewRect.height; EditorGUI.PropertyField(viewRect, iterator, GUIContent.none, false); } } } } } } }
サンプル
本来であればこのように表示されるが
今回の水平表示を利用した場合こちらのように表示される
IList の中に IList を利用した場合の対応は行っていないので IList が無いクラスでご利用ください
using System.Collections.Generic; using UnityEditor; using UnityEngine; public class SampleMonoBehaviour : MonoBehaviour { [SerializeField] private List<GameObject> _gameObjects; [SerializeField] private List<SampleClass> _samples = new List<SampleClass> { new SampleClass() }; [SerializeField] private Vector3 _vector3; [Serializable] private class SampleClass { [SerializeField] private int _intValue; [SerializeField] private string _stringValue; [SerializeField] private Vector2 _vector2Value; } } [CustomEditor(typeof(SampleMonoBehaviour))] public class SampleMonoBehaviourEditor : Editor { public override void OnInspectorGUI() { serializedObject.UpdateIfRequiredOrScript(); EditorGUILayout.PropertyField(serializedObject.FindProperty("_gameObjects")); ListHorizontal.Draw(serializedObject.FindProperty("_samples")); EditorGUILayout.PropertyField(serializedObject.FindProperty("_vector3")); serializedObject.ApplyModifiedProperties(); } }