16
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

エディタ拡張でクラスの折り畳み等を再現する

Posted at

エディタ拡張をしていると、クラスや配列を折りたたむ時のアレを実装することがありますよね。

Unity Personal (64bit) - Untitled - EditorExtensionSample - PC, Mac & Linux Standalone_ DX11 2016-08-20 03.39.13.png
これです。

これは Foldout というようですが、これの実装ですごい回り道をしてしまったのでメモ的に書いておきます。

以下のようなクラスがあるとします。

FoldoutTest.cs

using UnityEngine;

public class FoldoutTest : MonoBehaviour {

    [System.Serializable]
    private class SampleClass
    {
        [SerializeField] string hoge;
        [SerializeField] int fuga;
    }

    [SerializeField] SampleClass sampleClass;
}

このコンポーネントを適当なオブジェクトに張り付けてインスペクターに表示させると以下のようになりますね。

Unity Personal (64bit) - Untitled - EditorExtensionSample - PC, Mac & Linux Standalone_ DX11 2016-08-20 03.45.53.png

このSample Classという部分の表示ですが、EditorGUILayout.PropertyField()を使えば簡単にできます。

using UnityEditor;

[CustomEditor(typeof(FoldoutTest))]
public class FoldoutTestEditor : Editor {

    SerializedProperty sampleClass;

    void OnEnable()
    {
        sampleClass = serializedObject.FindProperty("sampleClass");
    }

    public override void OnInspectorGUI()
    {
        EditorGUILayout.PropertyField(sampleClass);        
    }
}

Unity Personal (64bit) - Untitled - EditorExtensionSample - PC, Mac & Linux Standalone_ DX11 2016-08-20 03.49.40.png

簡単ですね。ちゃんとクリックすれば開いたり閉じたりといった動作をしてくれます。
あとはクラス内の要素も描画して、ついでに先頭に編集不可能なスクリプトのプロパティフィールドも表示します。

using UnityEditor;

[CustomEditor(typeof(FoldoutTest))]
public class FoldoutTestEditor : Editor {

    SerializedProperty script;
    SerializedProperty sampleClass;
    SerializedProperty hoge, fuga;

    void OnEnable()
    {
        script = serializedObject.FindProperty("m_Script");
        sampleClass = serializedObject.FindProperty("sampleClass");
        hoge = sampleClass.FindPropertyRelative("hoge");
        fuga = sampleClass.FindPropertyRelative("fuga");
    }

    public override void OnInspectorGUI()
    {
        // スクリプト名を表示する. 編集はできないようにする.
        EditorGUI.BeginDisabledGroup(true);
        EditorGUILayout.PropertyField(script);
        EditorGUI.EndDisabledGroup();
        
        EditorGUILayout.PropertyField(sampleClass);
        
        if(sampleClass.isExpanded)
        {
            EditorGUI.indentLevel++;
            EditorGUILayout.PropertyField(hoge);
            EditorGUILayout.PropertyField(fuga);
            EditorGUI.indentLevel--;
        }
    }
}

Unity Personal (64bit) - Untitled - EditorExtensionSample - PC, Mac & Linux Standalone_ DX11 2016-08-20 03.45.53.png

できました!クラスの開閉状態はSerializedProperty.isExpandedで調べられます。

こうすれば、拡張するクラス側に#UNITY_EDITORで囲った開閉管理用変数を用意してFoldoutの描画や範囲内のクリック判定を自前でしたり、クラスが配列だった場合に増減の瞬間開閉管理用変数を操作する苦労とかしなくてすみますね!
ぼくも2度としたくないので次からはこの方法を取るようにします。

16
11
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?