UnityのEditorを拡張して自前のメニュー項目を表示する

今回はUnityのメニューに自作のメニューを表示させ、メニュー項目を選択した時に何らかの処理をさせたいと思います。

Unityのメニューとはエディターの上の方に表示されている部分ですね。

Unityのメニューの部分

FileやEdit等をマウスでクリックしそれぞれのメニュー項目を選択して色々な処理を実行する事が出来ます。

そのUnityのメニューに自前のメニューを追加したり、メニューに項目を追加し、項目を選択した時に何らかの処理を実行させてみたいと思います。

スポンサーリンク

エディターを拡張するスクリプトを配置するフォルダ

今回はUnityのエディターを拡張しますが、

UnityのEditor拡張をしてインスペクタをカスタマイズする
UnityのEditor拡張を利用してインスペクタのカスタマイズをしてみたいと思います。

の記事で作成したスクリプトのようにEditorクラスを継承して新しいクラスを作成するわけではないのでEditorフォルダにスクリプトを配置する必要はありません。

ですが、エディターを拡張するので今回は混乱しないようにEditorフォルダにスクリプトを配置してやっていこうと思います。

MenuItemTestというスクリプトを作成しAssets/Editorフォルダに配置します。

Unityのメニューに項目を追加する方法

Unityのメニューに項目を追加するにはMenuItemアトリビュートをメソッドに追加します。

MenuItemアトリビュートの第1引数には追加するメニューの名前と階層を設定しスペース文字の後にホットキー(ショートカットキー)の設定をします。

ホットキーを設定しない場合は記述する必要はありません。

%がCtrl(MacはCmd)、#がShift、&がAltキーに対応しており、↑のスクリプトの例でいくとCtrlキーを押しながらキーボードのTキーを押すとこの項目をマウスで選択した時と同じ動作をします。

%#&は組み合わせて設定する事が出来、%#&tとすればCtrl+Shift+Altを押しながらTキーを押す必要があります。

%#&以外にも特殊記号はありますが、この記事の最後にあるリンク先のUnityのスクリプトリファレンスで確認してください。

すでにあるショートカットキーと同じ設定にならないようにする必要があります。

第2引数ではbool型の値を設定し、第1引数で指定したメニューの階層で同じものがあった時にtrueを設定するとその項目が選択される前にtrueで設定したメソッドの処理を実行する事が出来ます。

正直なところ文章だけだとわからないので後で作成するサンプルで確認すると早いと思います・・・・(^_^;)

第3引数がメニュー項目の表示優先度の設定で番号が低いほど項目の上の方に表示されます。

この優先度の数値が前の項目の優先度より10より大きくなった時は間に線が表示されるようになります。

自作のUnityメニューを作成するサンプル

Unityのメニューに項目を追加するやり方がわかったので、実際にサンプルを作成して実行してみましょう。

メニューアイテムの名前は 自作メニュー というメニューがありその中にいくつかの項目を作成しました。

メソッドはクラスメソッド(staticを付ける)にします。

メソッド名は自分がわかりやすいように付けてください。

OutputConsoleとIsValidateメソッドのMenuItemの第1引数が同じですが、IsValidateの第2引数がtrueとなっているのでOutputConsoleより前に実行されます。

IsValidateでは選択されているオブジェクトがゲームオブジェクトであればtrueを返しOutputConsoleが実行出来ます。

それ以外のオブジェクトを選択している時はfalseになるのでメニュー項目の項目1自体がグレー表示され選択出来ないようになります。

項目1と項目2の優先度は11違うので間に線が表示されるようになるはずです。

それぞれの項目にはホットキーを設定し、キーボードで処理を実行出来るようにしています。

それでは確認してみましょう。

↑のようになりました。

最初に項目1を選択しようとしますが、Assetsエリアで選択しているオブジェクトがゲームオブジェクトでない為IsValidateメソッドでfalseが返されOutputConsoleは実行できません。

項目1と項目2の間には線が表示され、優先度の違いも確認出来ました。

動画の最後の方でCtrl+Shift+Alt+Tキーを押して項目3を実行しています。

最終的にTキーを押して処理を実行していますが、このTキーはすでに単独で押す事で他の動作をするショートカットキーとして登録されている為ゲームオブジェクト操作のアイコンが切り替わっています。

すでにあるメニューに項目を追加するサンプル

さきほどは自作のメニューの項目を作りましたが、次はすでにあるメニューに項目を追加するサンプルを作成してみます。

MenuItemTestスクリプトにメソッドを追加します。

MenuItemアトリビュートを取りつけたメソッドではMenuCommand型の引数を受け取る事が出来ます。

ゲームオブジェクト作成項目

CreateGameObjectメソッドでは空のゲームオブジェクトを作成し、受け取ったMenuCommandのコンテキスト(選択中のゲームオブジェクト)を親に設定します。

Undo.RegisterCreatedObjectUndoでCtrl+Zキーを押した時に元に戻す事が出来るように設定します。

ここでUndo登録をしないとゲームオブジェクトを作成した後、Ctrl+Zキーを押してもゲームオブジェクトを作成した事を取り消せません。

Selection.activeObject = obj;

をする事で今作成したゲームオブジェクトを選択状態にしています。

Rigidbodyコンポーネント取りつけ項目

AddComponentToObjectでは

Undo.AddComponent (Selection.activeGameObject);

で選択中のゲームオブジェクトにRigidbodyコンポーネントを取りつけ、

Undoにも登録します。

Assetsエリアにあるゲームオブジェクトを選択している時にも追加する事が出来ますが、選択中のオブジェクトがスクリプト等だった場合は当然エラーになります。

そこら辺のエラー対応は前のサンプルで使ったMenuItemの第2引数を使うといいかもしれません。

コメントにしているのはUndo登録をしないコンポーネントの取り付けです。

こちらの場合はコンポーネントの取り消しをCtrl+Zキーでは出来ません。

ゲームオブジェクトの位置と角度を設定する項目

DefaultPositionメソッドでは選択しているゲームオブジェクトの位置と角度を設定しています。

Undo.RecordObject (obj.transform, “Change Position & Rotation”);

でこの行以降で変更したobjのtransform情報に関する変更をUndoに登録します。

その為その後に実行するpositionとrotationの変更をCtrl+Zキーで元に戻す事が出来るようになります。

ゲームオブジェクトの作成と操作の実行

サンプルが出来たので実行してみましょう。

↑のようにメニュー項目からゲームオブジェクトの作成をし、Rigidbodyを取りつけ、位置と角度を変更した後Undo操作ですべての処理を取り消しています。

コンテキストメニュー項目の追加

Editorを継承して作成したクラスでコンテキストメニュー項目を追加する事が出来ましたが、今回はMenuItemで追加してみます。

MenuItemTestスクリプトにメソッドを追加します。

MenuItemの第1引数をCONTEXTから始めるとインスペクタのコンポーネントのタイトルを右クリック、右上の歯車を押した時のメニュー項目を追加する事が出来ます。

今回のサンプルではCharacterControllerコンポーネントのコンテキストメニューを追加してます。

コンテキストメニュー項目を選択するとCharacterControllerのradiusが3に変更されます。

↑のように空のゲームオブジェクトにCharacterControllerを取りつけ右クリックでコンテキストメニューを表示し『半径を3にする』項目を選択すると、

CharacterControllerのradiusが3になりました。

終わりに

Unityのメニュー項目の追加は結構簡単に出来てしまいました!

Undoの登録の部分がちょっとわかり辛いところではありますが、通常のスクリプトを記述するのと大差はありません。

よく使う機能等はメニュー項目を作成し実行させるようにしておくと作業効率がよくなるかもしれませんね。

今回はわかりやすいように項目名を日本語表記していますが、通常はアルファベット表記の方がいいかもしれません。

参考サイト

Unityスクリプトリファレンス-MenuItem-

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます