- 導入
- 作成したクラス
- プログラムの解説
- [CustomEditor(typeof("編集したいクラス名"))]
- serializedObject
- serializedObject.FindProperty("編集する変数名")
- void OnEnable()
- SerializedProperty.arraySize
- public override void OnInspectorGUI()
- serializedObject.Update() & serializedObject.ApplyModifiedProperties()
- EditorGUILayout.LabelField("文字列");
- SerializedProperty.GetArrayElementAtIndex(i)
- EditorGUILayout.PropertyField(SerializedProperty, new GUIContent(stat.ToString()));
- 動作確認
導入
前回(Unity エディタ拡張(publicリストの各要素に名前を付ける) - ミドリ黄のプログラミングメモノート)の記事ではpublicなリストに対してEditor拡張で要素の名前を変更したが、今回はprivateな変数などに対しても編集できるようにする
作成したクラス
Enemyクラス
- 敵のステータスを保存するためのクラス
- このクラスのリスト「stats」をエディタ拡張により表示するのが今回の目的。
using System.Collections.Generic; using UnityEngine; public enum Stat { Hp, Attack, Defense, } public class Enemy : MonoBehaviour { [SerializeField] List<int> stats; }
エディタ拡張のためのクラス
解説は後述
using UnityEngine; using UnityEditor; using System; [CustomEditor(typeof(Enemy))] public class EnemyEditor : Editor { int ListSize => Enum.GetValues(typeof(Stat)).Length;//enum Statの長さ SerializedProperty prop;//statsを格納する private void OnEnable() { //statsを取得 prop = serializedObject.FindProperty("stats"); //配列の長さを指定 if (prop.arraySize != ListSize) { //更新 serializedObject.Update(); prop.arraySize = ListSize; //保存 serializedObject.ApplyModifiedProperties(); } } public override void OnInspectorGUI() { //更新 serializedObject.Update(); //リストの名前を記載 EditorGUILayout.LabelField("ステータス"); //各要素を描画 for (int i = 0; i < ListSize; i++) { //表示するステータス名前 Stat stat = (Stat)Enum.ToObject(typeof(Stat), i); //表示 EditorGUILayout.PropertyField(prop.GetArrayElementAtIndex(i), new GUIContent(stat.ToString())); } //保存 serializedObject.ApplyModifiedProperties(); } }
プログラムの解説
[CustomEditor(typeof("編集したいクラス名"))]
- 編集するクラス名を設定することができます。
serializedObject
- 自分自身も正確には把握できていませんが、現在は、「『CustomEditor』で指定したスクリプトがアタッチされているオブジェクトの情報(?)」という風に考えています。
serializedObject.FindProperty("編集する変数名")
- 「CustomEditor」で指定したクラスの指定した変数をSerializedProperty型で取り出せます。
- privateな変数でも参照することが可能です。
void OnEnable()
- 「CustomEditor」で指定したクラスをアタッチしたGameObjectなどを選択したときに呼び出されます。
- 初期設定などに使用
SerializedProperty.arraySize
- SerializedPropertyが配列やリストであったときのその長さを示す
- SerializedPropertyが配列やリストでないときはエラー
public override void OnInspectorGUI()
- MonoBehaviorのUpdate関数のように繰り返し呼び出されます。
- メインの処理を記述します。
serializedObject.Update() & serializedObject.ApplyModifiedProperties()
- 変更を保存したり、オブジェクトの更新などに使用
- 詳しい働きはよくわかんないです。
EditorGUILayout.LabelField("文字列");
- 指定した文字列をインスペクター上に表示します。
- 幅はEditorGUIUtility.labelWidthを書き換えることで変更できます(今回は変更なし)。
SerializedProperty.GetArrayElementAtIndex(i)
- 指定したSerializedPropertyが配列やリストであったときに、そのi番目の要素をSerializedProperty型で取得
EditorGUILayout.PropertyField(SerializedProperty, new GUIContent(stat.ToString()));
- SerializedPropertyをインスペクターに表示します。
- 第2引数で表示名などを設定できます。
- int, string, Listなど大体の型は表示できた。
動作確認
Enemyクラスをシーン上の任意のゲームオブジェクトにアタッチするとこのように編集できます。