【Unity】【エディタ拡張】Unityを閉じてもEditorWindowの状態を保つ方法

Unityを再起動してもスクロール位置や折りたたみの状態など、EditorWindowの状態を保つ方法です。

問題点

例えば次のような折りたためるGUIを作ったとします。

f:id:halya_11:20181212133157p:plain

いま、Unityを再起動してもこの折りたたみ状態を保ちたいとします。
まず誤った実装をしてみます。

using UnityEngine;
using UnityEditor;

public class ExampleWindow : EditorWindow 
{
    private bool _foldOut;

    [MenuItem("Window/Example Window")]
    private static void Open()
    {
        GetWindow<ExampleWindow>("Example");
    }

    private void OnGUI()
    {
        _foldOut    = EditorGUILayout.Foldout(_foldOut, "FoldOut");
        if (_foldOut) {
            using (new EditorGUI.IndentLevelScope()) {
                EditorGUILayout.LabelField("Example Element");
                EditorGUILayout.LabelField("Example Element");
                EditorGUILayout.LabelField("Example Element");
            }
        }
    }
}

折りたたみを開いた状態にしてUnityを再起動してみます。

f:id:halya_11:20181212133217p:plain

折りたたみ状態が戻ってしまいました。

解決方法

解決方法はシンプルで、保持したい値をシリアライズするだけです。

EditorWindowでシリアライズされた値はWindowを閉じるまで保持されます。
Windowを閉じなければ、Unityを閉じても値は破棄されません。

using UnityEngine;
using UnityEditor;

public class ExampleWindow : EditorWindow 
{
    // シリアライズする
    [SerializeField]
    private bool _foldOut;

    [MenuItem("Window/Example Window")]
    private static void Open()
    {
        GetWindow<ExampleWindow>("Example");
    }

    private void OnGUI()
    {
        _foldOut    = EditorGUILayout.Foldout(_foldOut, "FoldOut");
        if (_foldOut) {
            using (new EditorGUI.IndentLevelScope()) {
                EditorGUILayout.LabelField("Example Element");
                EditorGUILayout.LabelField("Example Element");
                EditorGUILayout.LabelField("Example Element");
            }
        }
    }
}

これでUnityを再起動しても値が保持されるようになりました。