【Unity】【エディタ拡張】インスペクタの表示項目を動的に変更する 
2016/11/22 Tue [edit]
インスペクタである値を設定すると、それに対応したパラメタ設定だけを表示したいときってあるよね。幸いにも「Editor」クラスを継承して「OnInspectorGUI()」 を override すれば、元のスクリプトを変更せずに表示を切り替えられるので、試しに設定項目の表示切り替えをやってみよう。
(※) Unity 5.4.3f1 / Windows10 で確認

せっかくなので、用例は前回作った「独自のギズモを表示する」のスクリプトをそのまま使って、形状(Shape)を切り替えたときに「球」「箱」「線」に対応した設定パラメタだけを表示するようにしてみよう。各形状パラメタは「MySphere」「MyCube」「MyLine」クラスで保持されているが、実際に必要なのは「Shape」(形状)に対応するパラメタだけなので、1つだけ表示した方がインスペクタがスッキリする。以下は元の「独自ギズモを表示する」スクリプトとなる。
●球/箱/線状を切り替えられる独自ギズモを表示するスクリプト(→前回のと同じもの)
using UnityEngine;
using System.Collections;
/** 独自 Gizmo (球,箱,線 状) */
public class MyGizmo : MonoBehaviour {
/** 形状を表す定数 */
[System.Serializable]
public enum Shape {
Sphere = 0,
Cube,
Line,
}
public bool visible = true; //可視状態
public Color color = Color.yellow; //色
public Shape shape = Shape.Sphere; //形状
public MySphere sphereParam = new MySphere(0, 0, 0, 1); //球状のパラメタ
public MyCube cubeParam = new MyCube(0, 0, 0, 1, 1, 1); //箱状のパラメタ
public MyLine lineParam = new MyLine(0, 0, 0, 1, 1, 1); //線状のパラメタ
void OnDrawGizmos() {
if (!visible) {
return;
}
Gizmos.color = color;
//Gizmo はワールド座標指定なので、相対座標指定の場合はマトリクス変換で移動する
Gizmos.matrix = Matrix4x4.TRS(this.transform.position, this.transform.rotation,
this.transform.localScale);
switch (shape) {
case Shape.Sphere:
Gizmos.DrawSphere(sphereParam.center, sphereParam.radius);
break;
case Shape.Cube:
Gizmos.DrawCube(cubeParam.center, cubeParam.size);
break;
case Shape.Line:
Gizmos.DrawLine(lineParam.from, lineParam.to);
break;
}
}
}
/** 球状パラメタ */
[System.Serializable]
public class MySphere
{
public Vector3 center = Vector3.zero;
public float radius = 1f;
public MySphere(float x, float y, float z, float radius) {
this.center = new Vector3(x, y, z);
this.radius = radius;
}
}
/** 箱状パラメタ */
[System.Serializable]
public class MyCube
{
public Vector3 center = Vector3.zero;
public Vector3 size = Vector3.one;
public MyCube(float x, float y, float z, float scaleX, float scaleY, float scaleZ) {
this.center = new Vector3(x, y, z);
this.size = new Vector3(scaleX, scaleY, scaleZ);
}
}
/** 線状パラメタ */
[System.Serializable]
public class MyLine
{
public Vector3 from = Vector3.zero;
public Vector3 to = Vector3.one;
public MyLine(float x1, float y1, float z1, float x2, float y2, float z2) {
this.from = new Vector3(x1, y1, z1);
this.to = new Vector3(x2, y2, z2);
}
}
このスクリプトでは画像の一番上のように各形状のパラメタがインスペクタに全て表示される。このパラメタ部分を「Shape」(形状定数)を変更したら、それに対応するパラメタだけを表示するように、もう1つ「MyGizomoEditor」(名前は任意で良い)を作成しよう。完成したスクリプトは以下のようになる。なお、カスタムエディタ(インスペクタ)機能のスクリプトは「Editor」というフォルダを作って、そこに置く必要がある(※ルートでなくても良い)。

●MyGizmo の Shape によってインスペクタを動的に変更するスクリプト
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor (typeof(MyGizmo))]
public class MyGizmoEditor : Editor {
public override void OnInspectorGUI() {
MyGizmo obj = target as MyGizmo;
obj.visible = EditorGUILayout.Toggle("Visible", obj.visible);
obj.color = EditorGUILayout.ColorField("Color", obj.color);
obj.shape = (MyGizmo.Shape)EditorGUILayout.EnumPopup("Shape", obj.shape);
EditorGUI.indentLevel++; //インデントを入れる
switch (obj.shape) {
case MyGizmo.Shape.Sphere:
obj.sphereParam.center = EditorGUILayout.Vector3Field("Center", obj.sphereParam.center);
obj.sphereParam.radius = EditorGUILayout.FloatField("Radius", obj.sphereParam.radius);
break;
case MyGizmo.Shape.Cube:
obj.cubeParam.center = EditorGUILayout.Vector3Field("Center", obj.cubeParam.center);
obj.cubeParam.size = EditorGUILayout.Vector3Field("Size", obj.cubeParam.size);
break;
case MyGizmo.Shape.Line:
obj.lineParam.from = EditorGUILayout.Vector3Field("From", obj.lineParam.from);
obj.lineParam.to = EditorGUILayout.Vector3Field("To", obj.lineParam.to);
break;
}
EditorGUI.indentLevel--; //インデントを戻す
//obj.iconImage = EditorGUILayout.TextField("Icon Image", obj.iconImage); //アイコン画像
EditorUtility.SetDirty(target);
}
}
注意点としては、継承するのはいつもの「MonoBehaviour」ではなく「Editor」(要:using UnityEditor;)であることと、「[CustomEditor (typeof(MyGizmo))]」「MyGizmo obj = target as MyGizmo;」のようにカスタム対象となるスクリプト(ここでは「MyGizmo」)を指定することだ。
あとは「OnInspectorGUI()」内で「EditorGUILayout」(または「EditorGUI」)を使って、すべての表示項目の入力フィールド(チェックボックスやスライダーなども同様)を表示し、戻値をセットしていくだけだ。クラスや構造体のメンバ(プロパティ)なども同様にすれば良い。アイコン画像についてはコメントアウトしてあるが、これは前回の「ギズモのアイコンを表示する」に対応する場合の例なので記事を参照して欲しい。なお、ここで表示しなかったものは全て非表示となる。つまりある値によって表示する項目を分岐すれば、表示切り替えが可能となるわけだ。
他にも入力値制限や細かいカスタムインスペクタの使い方などは以下に資料を載せておこう。
(参考資料)
・カスタムエディタ編 Inspectorが変わる!
・インスペクタで設定できる値を動的に変更する【Unity】【エディタ拡張】
(関連記事)
【Unity】インスペクタの値を保持したまま変数をリネームする
【Unity】【C#】独自のギズモを表示する
【Unity】【C#】FPS(フレームレート)をリアルタイムに測定して表示するv2(4隅選択可能で、画面サイズの変更にも対応版)
- 関連記事
トラックバック
トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/229-0a80ed37
この記事にトラックバックする(FC2ブログユーザー)
| h o m e |