【Unity】【エディタ拡張】GenericMenuの表示名にスラッシュを使う(階層構造の区切り文字にしない方法)

Unityのエディタ拡張でGenericMenuのメニュー名にスラッシュを使う方法です。

やりたいこと

Unityのエディタ拡張で、以下のようにGenericMenuのアイテム名にスラッシュを含めることを考えます。

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public sealed class Example : EditorWindow
{
    private void CreateGUI()
    {
        // 適当にGenericMenuを開くためのボタンを作る
        var root = rootVisualElement;
        var button = new Button();
        button.text = "Open ContextMenu";
        button.clicked += () =>
        {
            // アイテム名にスラッシュを入れる
            var itemName = "First / Second";
            
            // GenericMenuを表示
            var genericMenu = new GenericMenu();
            genericMenu.AddItem(new GUIContent(itemName), false, () => Debug.Log("Clicked!"));
            genericMenu.ShowAsContext();
        };
        root.Add(button);
    }

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

GenericMenuの仕様として、アイテム名にスラッシュが含まれる場合には階層構造として認識されるため、この場合には下図のように階層表示が行われます。

階層表示

スラッシュをそのまま表示する

上述の通り、スラッシュを階層構造として扱うのはGenericMenuの仕様なのでスマートな解決策はありませんが、以下のスレッドにHackyな方法が紹介されていました。

https://answers.unity.com/questions/398495/can-genericmenu-item-content-display-.html

これを参考に、以下のようにUnicodeを指定してスラッシュを置換することで、スラッシュをそのまま表示することができます。

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public sealed class Example : EditorWindow
{
    private void CreateGUI()
    {
        var root = rootVisualElement;
        var button = new Button();
        button.text = "Open ContextMenu";
        button.clicked += () =>
        {
            var itemName = "First / Second";
            // Unicodeを指定して置換
            itemName = itemName.Replace("/", "\u2215");
            
            var genericMenu = new GenericMenu();
            genericMenu.AddItem(new GUIContent(itemName), false, () => Debug.Log("Clicked!"));
            genericMenu.ShowAsContext();
        };
        root.Add(button);
    }

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

実行結果は以下の通りです。

スラッシュをそのまま表示
スラッシュが表示されていることを確認できました。

参考

answers.unity.com