SerializeField書いても出てこない!
Unityでガリガリ書いていると、あぁこの変数SerializeFieldで出てくれればよいのに…と思うことが多いですよね。
またUniRxのReactiveCollectionの中身をデバッグしたい、という話があったのでどうすればよいか調べてみました。
エディタ拡張を使う
簡単なものであればListに毎回コピーすればよいけど、コスト的に気になるし二重でデータがあるのは気持よくはないね…
というわけで CustomEditor を使えば楽に書けるそうなので、実際にやってみました。
コード(int型)
using UnityEngine;
using UnityEditor;
using UniRx;
public class DebugReactiveCollection : MonoBehaviour {
private ReactiveCollection<int> intCollection = new ReactiveCollection<int>();
private void Start()
{
// テスト
intCollection.Add(1);
intCollection.Add(1);
// UniRxの処理
intCollection.ObserveRemove()
.Subscribe(i => Debug.Log("Remove Item:" + i.ToString()));
intCollection.ObserveAdd()
.Subscribe(i => Debug.Log("Add Item :" + i.ToString()));
}
#if UNITY_EDITOR
// デバッグ確認用
[CustomEditor(typeof(DebugReactiveCollection), true)]
public class intCollectionPreview : Editor
{
int additem = 0;
public override void OnInspectorGUI()
{
// 親クラスを参照
DebugReactiveCollection _drc = (DebugReactiveCollection)target;
ReactiveCollection<int> _iCol = _drc.intCollection;
int _count = _iCol.Count;
if( _count == 0)
{
EditorGUILayout.HelpBox("No exist items or No runtime.", MessageType.None);
return;
}
//リストの表示
for( int i = 0; i < _count; i++)
{
EditorGUILayout.BeginHorizontal();
_iCol[i] = EditorGUILayout.IntField("Item" + i.ToString(), (_iCol[i]));
if( GUILayout.Button("Delete"))
{
_iCol.RemoveAt(i);
EditorGUILayout.EndHorizontal();
return;
}
EditorGUILayout.EndHorizontal();
}
// 追加のGUI
EditorGUILayout.LabelField(" ");
EditorGUILayout.BeginHorizontal();
additem = EditorGUILayout.IntField("Add Index ->", additem);
if (GUILayout.Button("Add"))
{
_iCol.Add(additem);
EditorGUILayout.EndHorizontal();
return;
}
EditorGUILayout.EndHorizontal();
}
}
#endif
}
動作例
Inspectorに配列を操作するところが出てきた。またUniRxの監視もちゃんとできている。
おわりに
エディタ拡張の初歩としてもよいと思いますし、ReactiveCollection以外でも使える方法ですので、ぜひ困ったときにやってみましょう。
参考
https://anchan828.github.io/editor-manual/web/part1-editorwindow.html
https://gamedev.stackexchange.com/questions/137590/how-to-create-custom-inspector-to-display-generic-stackt-class