この記事でのバージョン
Unity 2018.2.14f1
はじめに
Unityのエディタ拡張にはMenuItemというメニューを追加したい時に使える属性があります。
このMenuItemは簡単かつ便利なので、知っていおいた方が良いですし、
エディタ拡張の入門としてもオススメです。
ただ、意外と多機能なのでMenuItem自体は使っていても、知らない使い方があるかもしれません。
[MenuItem("自作メニュー/MenuItemは/意外と/多機能")] private static void NoMeaning() { } [MenuItem("自作メニュー/Shortcut #&g+")] private static void Shortcut() { } [MenuItem("自作メニュー/CheckMark")] private static void CheckMark() { string menuPath = "自作メニュー/CheckMark"; bool isChecked = Menu.GetChecked(menuPath); Menu.SetChecked(menuPath, !isChecked); } [MenuItem("自作メニュー/Validate")] private static void Validate() { } [MenuItem("自作メニュー/Validate", validate = true)] private static bool ValidateValidation() { return Application.isPlaying; } [MenuItem("自作メニュー/Priority1", priority = 1)] private static void Priority1() { } [MenuItem("自作メニュー/Priority100", priority = 100)] private static void Priority100() { }
という事で今回はこのMenuItemについてまとめてみました!
なお、他にもこんなことが出来るみたいなのがあれば、ご一報頂けると幸いです。
目次
- はじめに
- 目次
- 基本的な使い方
- ショートカットキー(ホットキー)の設定
- メニューの追加場所を変える
- 無効にして使えないようにする
- チェックマークを付ける
- 並びの優先度を指定、区切り線を追加
- メニューをプログラムから実行する
基本的な使い方
MenuItemは最初にも述べた通り、Unityエディタにメニューを追加するためのものです。
使い方は簡単、staticなメソッド(privateでもOK)にMenuItemという属性を付けるだけ。
この時、引数にメニューを表示する場所を指定します。
ただし、"ShowLog"のように直で指定する事は出来ず、必ず"Tools/ShowLog"のように階層を付けます。
using UnityEngine; using UnityEditor; public class MenuItemSample{ /// <summary> /// ログを表示する /// </summary> [MenuItem("Tools/ShowLog")] private static void ShowLog() { Debug.Log("ログ"); } }
このメニューは、Windowなどの最初からあるメニューの下に追加する事も可能ですし、
[MenuItem("Window/ShowLog")]
メニュー名を日本語にしたり、階層を増やすことも可能です。
[MenuItem("宝箱/取る/本当に?/絶対?/どうしても?")] private static void AAA() {} [MenuItem("宝箱/取らない")] private static void BBB() {}
ショートカットキー(ホットキー)の設定
以前、記事にもしましたが、MenuItemはショートカットキー(ホットキー)を設定する事も可能です。
使い方は以下のように、
引数のメニューを表示する場所の後にスペースを空けてキーを追加するだけです。
/// <summary> /// ログを表示する(Shift + Alt + gキーを押すと実行される) /// </summary> [MenuItem("Tools/ShowLog #&g+")] private static void ShowLog() { Debug.Log("ログ"); }
また、アルファベット以外に設定可能なキーは以下の通りです。
- % : CTRL (Windows) または command (OSX)
- # : Shift
- & : Altキー
- LEFT/RIGHT/UP/DOWN : 方向キー
- F1…F2 : Fキー
- HOME, END, PGUP, PGDN : HOME、END, PageUp, PageDown
ただし、一つのキー単独で指定する場合はアンダーバー(_)をキーの前に置く必要があります。
/// <summary> /// ログを表示する(gキーを押すと実行される) /// </summary> [MenuItem("Tools/ShowLog _g")] private static void ShowLog() { Debug.Log("ログ"); }
なお、デフォルトのショートカットキーと同じものを設定してしまうと、
デフォルトの方が優先されてしまいます。
ちなみにUnity 2019.1からは新システムShortcut Managerがあるので、
ショートカットが重複してると警告を出してくれますし、
Shortcut Managerからショートカットの設定や、デフォルトの変更をする事も出来ます。
メニューの追加場所を変える
通常、MenuItemは画面上部に表示されますが、
特殊なパスを使えば別の所に追加する事も可能です。
その特殊なパスというのが以下の3つになります。
ProjectビューのCreate
パスの最初を"Assets/Create/"にするとProjectビューのCreateにメニューを追加出来ます。
[MenuItem("Assets/Create/ShowLog")] private static void ShowLog() { Debug.Log("ログ"); }
こちらも、上部に通常通り表示されます。
Projectビュー上で右クリックした所
パスの最初を"Assets/"にするとProjectビュー上で右クリックした所にメニューを追加出来ます。
[MenuItem("Assets/ShowLog")] private static void ShowLog() { Debug.Log("ログ"); }
なお、上部にも通常通り表示されます。
コンポーネントの歯車
パスの最初を"CONTEXT/コンポーネント名"にするとコンポーネントの歯車にメニューを追加出来ます。
例えばRigidBodyの場合だと以下のような感じ。
[MenuItem("CONTEXT/Rigidbody/ShowLog")] private static void ShowLog() { Debug.Log("ログ"); }
なお、引数にMenuCommandを付けると、実行したコンポーネントを取得する事が可能です。
[MenuItem("CONTEXT/Rigidbody/ShowLog")] private static void ShowLog(MenuCommand menuCommand) { //menuCommandから実行したRigidbodyを取得出来る Rigidbody rigidbody = menuCommand.context as Rigidbody; //Rigidbodyが付いてるゲームオブジェクトの名前をログで表示 Debug.Log(rigidbody.gameObject.name); }
もちろん自作のコンポーネントに追加する事も出来ます。
[MenuItem("CONTEXT/NewBehaviourScript/ShowLog")] private static void ShowLog() { Debug.Log("ログ"); }
なお、ContextMenuでも同様の事が可能です。
ただし、こちらはRigidbodyなどのデフォルトで用意されているものには使えません。
using UnityEngine; public class NewBehaviourScript : MonoBehaviour { [ContextMenu("ShowLog")] private void ShowLog(){ Debug.Log("ログ"); } }
余談ですがContextMenuItemを使えば、変数を右クリックした所にメニューを追加する事も出来ます。
この場合、第一引数に表示名、第二引数に実行するメソッド名を指定します。
using UnityEngine; public class NewBehaviourScript : MonoBehaviour { [ContextMenuItem("Reset", "ResetText")] public string Text = ""; //テキストを空にする private void ResetText() { Text = ""; } }
無効にして使えないようにする
MenuItemは同じパスでvalidateという引数をtrueにし、返り値をboolにすれば
そのメニューが使えるかどうかの判定用のメソッドに出来ます。
具体的には以下のような感じです。
[MenuItem("Tools/ShowLog")] private static void ShowLog() { Debug.Log("ログ"); } /// <summary> /// ShowLogが使えるか判定する用のメソッド /// </summary> [MenuItem("Tools/ShowLog", validate = true)] private static bool ShowLogValidation() { return !Application.isPlaying;//実行中は使えない }
チェックマークを付ける
MenuのSetCheckedを使えば、メニューにチェックを付けたり外したりも出来ます。
同様にMenuのGetCheckedを使えばチェックが付いてるかが分かります。
具体的には以下のような感じです。
//押す度にチェックが切り替わる [MenuItem("Tools/ChangeState")] private static void ChangeState() { //現在チェックされているかを取得する(デフォルトではチェックされていない) string menuPath = "Tools/ChangeState";//MenuItemで指定したパスと同じものを使う bool isChecked = Menu.GetChecked(menuPath); //逆のを設定する Menu.SetChecked(menuPath, !isChecked); }
なお、MenuItemを設定したメソッドと違う場所で使う事も可能です。
また、Unityエディタを再起動するとチェックは外れます。
並びの優先度を指定、区切り線を追加
MenuItemのpriorityという引数を使えば、並びの優先度を指定する事も可能です。
なおpriorityは低いほどメニューは上に表示され、同じ値を設定しても問題ありません。
さらにpriorityが付いていないか、priorityに11以上差をつければ区切り線が表示されます。
具体的には以下のような感じです。
[MenuItem("Tools/ShowLog1", priority = 1)] private static void ShowLog1() { Debug.Log("ログ"); } [MenuItem("Tools/ShowLog2", priority = 2)] private static void ShowLog2() { Debug.Log("ログ"); } [MenuItem("Tools/ShowLog50", priority = 50)] private static void ShowLog50() { Debug.Log("ログ"); } [MenuItem("Tools/ShowLog70", priority = 70)] private static void ShowLog70() { Debug.Log("ログ"); }
ただし1番近いやつからの差が11以上の時に区切り線が表示されるので、
後から間の値を設定し、幅が10以下になったら区切りが消えるので注意が必要です。
[MenuItem("Tools/ShowLog1", priority = 1)] private static void ShowLog1() { Debug.Log("ログ"); } [MenuItem("Tools/ShowLog2", priority = 2)] private static void ShowLog2() { Debug.Log("ログ"); } [MenuItem("Tools/ShowLog50", priority = 50)] private static void ShowLog50() { Debug.Log("ログ"); } //50と70の間に60を追加 [MenuItem("Tools/ShowLog60", priority = 60)] private static void ShowLog60() { Debug.Log("ログ"); } [MenuItem("Tools/ShowLog70", priority = 70)] private static void ShowLog70() { Debug.Log("ログ"); }
メニューをプログラムから実行する
EditorApplication.ExecuteMenuItemを使う事でメニューをプログラムから実行する事も可能です。