Unity エディタ拡張のチェックメニューのデフォルト値を設定する

前提

Unity エディタ拡張では Menu.SetChecked を使ってトグル式のメニュー項目を作成できます。

using UnityEditor;

public static class MyMenu
{
    private const string _menuPath = "MyMenu/My Flag";

    public static bool Flag = false;

    [MenuItem(_menuPath)]
    private static void SwitchFlag()
    {
        Flag = !Flag;

        Menu.SetChecked(_menuPath, Flag);
    }
}

このメニューを最初からチェックが入った状態にしたいときにちょっと詰まったのでメモ。

失敗パターン

初めは InitializeOnLoadMethod のタイミングで true にしてあげればよいと考えたのですが、このタイミングで Menu.SetChecked を呼び出しても無視されてしまうのか、うまくいきません。

// NG パターン

using UnityEditor;

public static class MyMenu
{
    private const string _menuPath = "MyMenu/My Flag";

    public static bool Flag = true;


    [InitializeOnLoadMethod]
    private static void Initialize()
    {
        Menu.SetChecked(_menuPath, Flag);
    }

    [MenuItem(_menuPath)]
    private static void SwitchFlag()
    {
        Flag = !Flag;

        Menu.SetChecked(_menuPath, Flag);
    }
}

結論

メニュー項目にはバリデート関数を定義できます。
やり方は MenuItem で 2 番目の引数 (validate) を true にし、そのメニューパスをアクティブにするかどうかを bool 型で返すメソッドをもう一つ定義します。
主にそのメニューを使ってほしくない場合などに非アクティブにする目的で使われますが、前述の目的で使うこともアリのようです。

// OK パターン

using UnityEditor;

public static class MyMenu
{
    private const string _menuPath = "MyMenu/My Flag";

    public static bool Flag = true;

    [MenuItem(_menuPath)]
    private static void SwitchFlag()
    {
        Flag = !Flag;

        Menu.SetChecked(_menuPath, Flag);
    }

    [MenuItem(_menuPath, validate = true)]
    private static bool SwitchFlagValidator()
    {
        // 初期値の設定。バリデート関数で実行する
        Menu.SetChecked(_menuPath, Flag);
        return true;
    }
}

初期値をチェックが入った状態にできました。

さらに: チェック状態を保持させる

もう一歩踏み込んで、エディタを閉じたりしてもチェック状態を覚えておくようにしてみます。そのためには EditorUserSettings.SetConfigValue および EditorUserSettings.GetConfigValue を使うのがよさそうです。

using UnityEditor;

public static class MyMenu
{
    private const string _menuPath = "MyMenu/My Flag";

    public static bool Flag = true;

    [InitializeOnLoadMethod]
    private static void InitializeFlag()
    {
        // セーブしていた値をロードする
        string flagValue = EditorUserSettings.GetConfigValue(_menuPath);
        if (!string.IsNullOrEmpty(flagValue))
        {
            Flag = string.Equals(flagValue, true.ToString(), System.StringComparison.OrdinalIgnoreCase);
        }
    }

    [MenuItem(_menuPath)]
    private static void SwitchFlag()
    {
        Flag = !Flag;

        Menu.SetChecked(_menuPath, Flag);

        // チェック状態を残すためセーブする
        EditorUserSettings.SetConfigValue(_menuPath, Flag.ToString());
    }

    [MenuItem(_menuPath, validate = true)]
    private static bool SwitchFlagValidator()
    {
        // 初期値の設定。バリデート関数で実行する
        Menu.SetChecked(_menuPath, Flag);
        return true;
    }
}

これで Unity プロジェクトごとにチェック状態を保存しておけるようになり、いい感じになりました。

コメント

タイトルとURLをコピーしました