【Unity】親子関係のあるメニュー表示(MenuItem)の区切りのルール

はじめに

UnityではMenuItem属性をメソッドにつけることで、メニューからメソッドを起動することができます。

エディタ拡張を使われている方はおなじみだと思いますが、個人的に表示制御(区切り、セパレータ)のルールが良くわかっていなかったのでここにまとめておきます。

色々とエディタ拡張を作っていると整理して表示したくなったのですが、意図通りにするのに検証が必要だったのでメモ代わりです。

ここで表示するスクリーンショットは通常は表示されないメニューの表示優先度を表示した状態で撮影しています。表示の仕方は下記のリンク先をご参照ください。
https://qiita.com/ayaha401/items/4ecbe72d4f7941b643e9

また、基本的なところは下記リンク先が素敵にまとめてくれているので、確認されるとよいかと思います。
https://kan-kikuchi.hatenablog.com/entry/MenuItem

区切り線が入るルール

基本的には項目間で優先度が11以上離れていると区切り線が発生します。

例えば以下のように設定した場合
OrigialMenu01の子要素であるItem01と02は10しか離れていないので、区切り線は発生せず、02と03の間は11離れているので区切り線が発生します。

    [MenuItem("OriginalMenu/OriginalMenu01/Item01", false, 0)]
    public static void OriginalMenu01_Item01() { }

    [MenuItem("OriginalMenu/OriginalMenu01/Item02", false, 10)]
    public static void OriginalMenu01_Item02() { }

    [MenuItem("OriginalMenu/OriginalMenu01/Item03", false, 21)]
    public static void OriginalMenu01_Item03() { }

    [MenuItem("OriginalMenu/OriginalMenu02/Item01", false, 22)]
    public static void OriginalMenu02_Item01() { }

    [MenuItem("OriginalMenu/OriginalMenu02/Item02", false, 23)]
    public static void OriginalMenu02_Item02() { }

    [MenuItem("OriginalMenu/OriginalMenu02/Item03", false, 24)]
    public static void OriginalMenu02_Item03() { }

さてここでOrigialMenu02の優先度をOrigialMenu01のItem03の続きからということで22から始めると困ったことに、親メニューの間にも区切り線が入ってしまいます。

これでは親同士の区切りはなしで、子だけに区切りを入れることができないように思ったのですが、親要素は親要素同士で比較されるので、OrigialMenu02のスタートを1からにすることで親間の区切りをなくすことができます。

    [MenuItem("OriginalMenu/OriginalMenu01/Item01", false, 0)]
    public static void OriginalMenu01_Item01() { }

    [MenuItem("OriginalMenu/OriginalMenu01/Item02", false, 10)]
    public static void OriginalMenu01_Item02() { }

    [MenuItem("OriginalMenu/OriginalMenu01/Item03", false, 21)]
    public static void OriginalMenu01_Item03() { }

    [MenuItem("OriginalMenu/OriginalMenu02/Item01", false, 1)]
    public static void OriginalMenu02_Item01() { }

    [MenuItem("OriginalMenu/OriginalMenu02/Item02", false, 2)]
    public static void OriginalMenu02_Item02() { }

    [MenuItem("OriginalMenu/OriginalMenu02/Item03", false, 3)]
    public static void OriginalMenu02_Item03() { }

このような優先度にすると親に区切りは入らない。

じゃあこの親の優先度はどのように決まるかというと、所属している子要素の一番優先度の高いもの(値が小さいもの)が親の優先度になります。

例えば「OriginalMenu01/Item03」の優先度を-10にしてみます。

するとほかは特に変えていませんが、親のOriginalMenu01の優先度が-10となり親のOriginalMenu02との優先度差が11になったので区切り線が追加されました。

思ってたのと違うときは再起動

staticクラスとstatic関数を使う関係か、優先度を適切に変えても意図通りに表示されない場合があります。

色々と弄っていると、いつの間にか下記のような警告が出ていることがある。。。

Cannot add menu item ‘OriginalMenu/OriginalMenu01/Item01’ for method ‘RuntimeMethodInfo.O3_Item01’ because a menu item with the same name already exists.

絶対これであっているはずなのに、意図した表示にならない場合には、Unityを再起動してみましょう。

メニューの描画が更新されて、その時点の正しい表示が反映されます。

(再起動しても、意図通りでない場合には多分何か間違ってます・・・)

さいごに

優先度設定は他の要素とも絡むので、適当に設定していると、なにがなにやら・・・となってしまいますね。

定期的に見直したいと思います。

Menu表示管理用の静的クラスを1つ作ってもよいかもしれません。

最後までお読みいただきありがとうございます!

コメント

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