unity.com
Unity 2020.2 の Inspector では、配列は並び替えが可能な Reorderable
なものに変わりました。
自作クラスのデフォルト表示
下記のように [Serializable]
を指定した自作クラスについても、手軽に Reorderable
なGUIを Inspector で確認できます。便利ですね。

using System;
using UnityEngine;
[Serializable]
public class TestObject
{
public GameObject Prefab;
public Vector3 Position;
public Vector3 Rotate;
}
public class TestComponent : MonoBehaviour
{
public TestObject[] TestObjects = {new TestObject(),};
}
けれど、ちょっと見づらいですね。イマイチポイントを挙げると以下のとおり。
- 一覧性に欠けている
- Foldoutを閉じた状態 :
Element 1
といった連番のラベル情報しか表示されない
- Foldoutを開いた状態 :
- → インデントを用いて、データのまとまりを表現したい
自作クラスのエディタ拡張
ということで、エディタ拡張を書いて解決をしてみます。
EditorGUILayout
は使えないので、 EditorGUI
で Rect をしっかり指定します。

using System;
using UnityEngine;
using UnityEditor;
[Serializable]
public class TestObject
{
public GameObject Prefab;
public Vector3 Position;
public Vector3 Rotate;
}
public class TestComponent : MonoBehaviour
{
public TestObject[] TestObjects = {new TestObject(),};
}
[CustomPropertyDrawer(typeof(TestObject))]
public class TestObjectDrawer : PropertyDrawer
{
private static float GetPropertyHeight(SerializedProperty property = null)
{
var height = property == null
? EditorGUIUtility.singleLineHeight
: EditorGUI.GetPropertyHeight(property, true);
return height + EditorGUIUtility.standardVerticalSpacing;
}
private static bool FoldoutField(ref Rect rect, SerializedProperty property, string label, string propertyName)
{
var prop = property.FindPropertyRelative(propertyName);
prop.isExpanded = EditorGUI.Foldout(rect, prop.isExpanded, GUIContent.none);
EditorGUI.PropertyField(rect, prop, new GUIContent(label));
rect.y += GetPropertyHeight(prop);
return prop.isExpanded;
}
private static void Field(ref Rect rect, SerializedProperty property, string label, string propertyName)
{
var prop = property.FindPropertyRelative(propertyName);
EditorGUI.PropertyField(rect, prop, new GUIContent(label), true);
rect.y += GetPropertyHeight(prop);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
position.height = EditorGUIUtility.singleLineHeight;
if (FoldoutField(ref position, property, "Prefab", "Prefab"))
{
EditorGUI.indentLevel++;
Field(ref position, property, "Position", "Position");
Field(ref position, property, "Rotate", "Rotate");
EditorGUI.indentLevel--;
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
var enableSkinName = property.FindPropertyRelative("Prefab");
var height = GetPropertyHeight(enableSkinName);
if (enableSkinName.isExpanded)
{
height += GetPropertyHeight(property.FindPropertyRelative("Position"));
height += GetPropertyHeight(property.FindPropertyRelative("Rotate"));
}
return height;
}
}
これでようやく使い物になりそうな見た目になりましたね。
ちょっとした気遣いで、UnityEditor上の作業はすごく楽になるので、「ゲームの内容には関係ないし・・」とか思わず、ちょいちょいっと書いていきましょい