【Unity】【UI Toolkit】Unity EditorでContextual Menu(右クリックメニュー)を使う

UI Toolkitで、Unity EditorのContextual Menu(右クリックメニュー)を使う方法についてまとめました。

Unity 2022.2.17

Contextual Menuとは?

Contextual Menuとは、Unity Editor上で右クリックを行った時に出現するメニューのことです。

Contextual Menu

UI Toolkitでは独自のUIに対してContextual Menuを追加する仕組みが用意されています。

本記事ではこれの使い方について紹介します。

Contextual Menuを実装する

それでは早速Contextual Menuを実装してみます。

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public sealed class ExampleWindow : EditorWindow
{
    public void CreateGUI()
    {
        var element = new VisualElement();
        element.style.backgroundColor = Color.red;
        element.style.width = 100;
        element.style.height = 100;

        // ContextualMenuManipulatorを生成
        var manipulator = new ContextualMenuManipulator(evt =>
        {
            // メニュー
            evt.menu.AppendAction("Example Menu", action => Debug.Log("Execute Example"));
            // 無効化状態のメニュー
            evt.menu.AppendAction("Disabled Menu", action => Debug.Log("Disabled Menu"),
                DropdownMenuAction.Status.Disabled);
            // セパレータ
            evt.menu.AppendSeparator();
            // チェック付きメニュー
            evt.menu.AppendAction("Checked Menu", action => Debug.Log("Checked Menu"),
                DropdownMenuAction.Status.Checked);
            // ユーザーデータ(任意のデータ)の使い方
            evt.menu.AppendAction("Menu with User Data",
                action => Debug.Log(action.userData),
                action => DropdownMenuAction.Status.Normal
                , "This is user data");
        });
        // ManipulatorのtargetにVisualElementを設定すると、
        // このVisualElementが右クリックされたときにコンテキストメニューが表示される
        manipulator.target = element;

        rootVisualElement.Add(element);
    }

    [MenuItem("Window/Example")]
    private static void Open()
    {
        GetWindow<ExampleWindow>();
    }
}

説明はコメントに書いた通りです。

ContextualMenuManipulatorを生成し、そのtargetプロパティに任意のVisual Elementをアサインすることで、そのVisual Elementが右クリックされた時にContextual Menuが表示されます。

動作確認

次に前節で作ったウィンドウの動作確認を行います。
Window > Exampleからウィンドウを開いて赤い要素を右クリックすると、以下の結果が得られます。

動作確認
正常にメニューが作成できていることを確認できました。

動的にメニューを追加する

ContextualMenuPopulateEventを使うと、登録先のUIが右クリックされてContextual Menuが開く時のコールバックを受け取れます。
これを利用して以下のように記述すると、登録先のUIのContextual Menuに対して動的にメニューを追加したり、上書きしたりできます。

element.RegisterCallback<ContextualMenuPopulateEvent>(evt =>
{
    // elementが開いたContextualMenuに対してメニューを追加する
    evt.menu.AppendAction("Runtime Example Menu", action => Debug.Log("Execute Example"));
    
    // メニューを削除して上書きことも
    //evt.menu.ClearItems();
    //evt.menu.RemoveItemAt(0);
});

参考

docs.unity3d.com