Unity MenuItem でメニューを追加し静的関数を呼び出す(2)

前回UnityMenuItem Attribute の 3 つのコンストラクタの引数の意味やショートカットキーについて紹介しました。

今回は Unity エディタに静的関数を呼び出すメニュー追加できる MenuItem 属性コンストラクタのツールヒントに出てきたプロパティについて紹介します。
結果として、コンストラクタの引数と同様に使うことでメニューから関数を呼び出す設定ができました。

※時間をかけて調べましたが、あまり実用的な内容ではありません
※コンストラクタで値を指定できるプロパティについては不明な点も残っています。
※具体的なプロパティについても公式の説明がみつけられない場合もあったので、検証結果としてお読みください。
※ Unity は 2022.3.14.f1、Visual Studio は Community 2022 Version 17.2.5 です。

MenuItem のオプション引数

MenuItem のコードを入力していると、プロパティという項目が引数として表示されていたので、それぞれの意味について調べました。
ContextMenu Attribute と似ている箇所が多いですが、プロパティは MenuItem だけ表示されました。

Unity MenuItem を Visual Studio でコードしていると表示されるプロパティ

editorModes = string[]

公式サイトの説明文を読むと、メニューアイテムを表示する EditorMode を複数指定できるようです。
指定しない場合は default mode でのみメニューアイテムが表示されます。

Specifies the Editor modes that the item is displayed for. If you don’t specify any Editor modes, the item is only displayed for the default mode.

(Google 翻訳)
項目が表示されるエディター モードを指定します。エディタ モードを指定しない場合、項目はデフォルト モードでのみ表示されます。

https://docs.unity3d.com/2021.2/Documentation/ScriptReference/MenuItem-editorModes.html

Editor Mode が何なのかはわかりませんでした。
ただ、サードパーティが Unity の Editor Mode の設定を変更する場合があるのかもしれないと、以下のサイトを見て思いました。

menuItem = string

説明は見つかりませんでしたが、実際に文字列をいれました。

[MenuItem("My/TestMenuItem4", menuItem = "abc")]
private static void TestMenuItem4()
{
    Debug.Log("TestMenuItem4 called.");
}

Unity エディタを開くとサブメニューをいれるようにとエラーログが出ました。

Unity MenuItem のプロパティ menuItem に abc と指定するとエラーログが表示されました。

前回と同じようにサブメニューをいれた itemName を設定するとメニューアイテムの名前が itemName のものではなく menuItem で指定したものに変わりました。

[MenuItem("My/TestMenuItem4", menuItem = "My/abc")]
Unity MenuItem のプロパティ menuItem で指定した文字列に itemName が上書きされました。

メニューアイテムを選択すると対応する関数が呼び出されログ出力されました。

Unity MenuItem のプロパティ menuItem で文字列を変更したメニューアイテムを選択すると対応する関数が呼び出されました。

公式サイトの説明は見つけられませんでしたが、 itemName を上書きする効果を確認できました。

priority = int

優先度を指定する priority 位置指定引数と同じならば、メニューの表示順が変わります。
次のコードを追記しました。

[MenuItem("My/TestMenuItem5", priority = 999)]
private static void TestMenuItem5()
{
    Debug.Log("TestMenuItem5 called.");
}

すでに [MenuItem(“My/TestMenuItem3”, false, 999)] と前に宣言した TestMenuItem3 で使われているので、同じ 999 にすると後に宣言した TestMenuItem5 は TestMenuItem3 の下に表示されました。

Unity MenuItem プロパティ priority = 999 にした結果、宣言順で同じ値のメニューの下に表示されました。

公式サイトの説明は見つけられませんでしたが、 priority オプション引数 を上書きする効果を確認できました。

validate = bool

isValidateFunction = true のときに同じ itemName と関連付けられる Validation Function の戻り値と同じならば、そのメニューアイテムの有効性を設定できあmす。
次のコードを追記しました。

[MenuItem("My/TestMenuItem6", validate = false)]
private static void TestMenuItem6()
{
    Debug.Log("TestMenuItem6 called.");
}

Validation Function の bool 型の戻り値とは違い、 validate = false にしてもメニューアイテムは有効で、選択するとログ出力もされました。

次にこのコードで試しました。前回説明した isValidateFunction と同様の使い方です。

[MenuItem("My/TestMenuItem6", validate = true)]
private static bool TestMenuItem6Validation()
{
    return false;
}

[MenuItem("My/TestMenuItem6", validate = false)]
private static void TestMenuItem6()
{
    Debug.Log("TestMenuItem6 called.");
}

isValidateFunction と同じ設定を行うフィールドのようで、前回と同じく Validation Function の戻り値に応じてメニューアイテムの有効 / 無効が切り替わりました。

公式サイトの説明は見つけられませんでしたが、 isValidateFunction オプション引数 を上書きする効果を確認できました。

コンストラクタの引数で指定できるプロパティとは

結局、今回紹介したものは、コンストラクタの引数 itemName, isValidateFunction, priority と同等のものでした。
EditorNames については不明な点も残りました。
あまり実用的な紹介ができず残念です。

そして最後までわからなかったのが、この コンストラクタ(X = Y) という形で指定できる Visual Studio のツールヒントでいうプロパティでした。
なんとかこれを自作クラスでも再現するために調べました。

Unity MenuItem のプロパティは = が後ろにつく形で文脈上存在する?

文脈上、フィールド a が存在する場合 func(a = 1); のような書き方ができるようなので、このクラスの MenuItem Attribute を記述する直前に

public static string menuItem2;

を追加してみると、候補のリストに menuItem2 フィールドとして表示されましたが、 menuItem = のように = はついていません。
また、menuItem = は、 MenuItem のメンバ変数 menuItem と同一でした。

Unity MenuItem のプロパティ menuItem は public メンバ変数のVisualStudioツールヒントの表示内容と同じ

結果としてSystem.Attribute を継承した際の public メンバ変数は Visual Studio のツールヒントでプロパティとして表示されることがわかりました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class TestConstructorOptionArg : System.Attribute
{
    public int optionInt;
    public TestConstructorOptionArg(string name) {}
}

public class StudyPropertyAttribute : MonoBehaviour
{
    [TestConstructorOptionArg("hoge", optionInt = 1)]
    public void TestConstructorOptionArgFunc() { }
}
C# System.Attribute を継承するとメンバ変数がプロパティとしてツールヒントに表示されました。

このことから System.Attribute を継承すると public メンバ変数をコンストラクタで設定できるように変化することがわかりました。
しかし、その変化の具体的な理由は不明です。

まとめ

今回紹介した MenuItem のコンストラクタで設定できるプロパティは、前回のコンストラクタの引数を上書きできる効果があり、プロパティを設定することでメニューから関数を呼び出すことが出来ました。
しかし、コンストラクタの引数を指定する場合と変化はわかりませんでした。

このコンストラクタで設定できるプロパティをどのように再現するかについては、具体的なコードによって再現できましたが、詳細は不明です。

今回はあまり実用的な話題ではありませんでしたが、時間をかけて調べた検証結果として報告させてください。

参照サイト Thank You!

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

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