4
3

Unityのツールバーにボタンを追加する方法(Unity 2021.2以降)

Last updated at Posted at 2023-12-11

PONOS Advent Calendar 2023 の12日目の記事です。

はじめに

二年前の記事で特定シーンの再生ボタンを追加する方法を記載しましたが、Unity2021.2以降のUI ToolKitが導入されて以降、動作しなくなっておりました。
こちらの解決を行うための記事となります。
シーン再生部分は変わらないため、ボタンの表示と調整方法について記載致します。
また、UI ToolKitのデバッグ方法も記載致します。

対象者

最新のUnityで自分だけのボタンや拡張を入れたい人向けになります。

UI ToolKitとはなにか

UI Toolkitとは、UnityのUIを作成する上で使用できる機能の1つです。
UI作成、エディタ拡張など幅広い範囲で使用でき、HTMLなどのウェブベースで作成できます。

ツールバーにボタンを追加する

実装

ツールバーを取得する設定

ツールバーのタイプを取得し保持しておくことで処理負荷を減らしています。

CustomToolbar.cs
/// <summary>
/// UnityEditor.ToolbarのType取得
/// </summary>
static readonly System.Type ToolbarType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.Toolbar");

エディタの更新に登録

スクリプトのコンパイル後にエディタの更新にイベントを登録することで、毎回表示されるようにしております。

CustomToolbar.cs
/// <summary>
/// スクリプトコンパイル後に呼び出せる処理
/// </summary>
[InitializeOnLoadMethod]
static void InitializeOnLoad()
{
    EditorApplication.update -= OnUpdate;
    EditorApplication.update += OnUpdate;
}

ツールバーの取得と保持

ツールバーの生成がずれる場合があるため、Updateでチェックしております。

CustomToolbar.cs
/// <summary>
/// 現在描画中のツールバー
/// </summary>
static ScriptableObject currentToolbar = null;
        
/// <summary>
/// Editorの描画更新に合わせて描画を更新する処理
/// </summary>
static void OnUpdate()
{
    if (currentToolbar == null)
    {
        var toolbars = Resources.FindObjectsOfTypeAll(ToolbarType);
        currentToolbar = toolbars.Length > 0 ? (ScriptableObject)toolbars[0] : null;
        if (currentToolbar != null)
        {
            AddHandler(currentToolbar);
        }
     }
}

描画設定

VisualElementを取得して、IMGUIContainerを設定できるようにしています。
VisualElementの取得としてツールバーの型から取得し、Q関数を使うことでツールバーのどこに表示させるかを決定できます。

設定名 描画
ToolbarZoneLeftAlign ツールバーの左のVisualElementを取得
ToolbarZonePlayMode プレイモードのVisualElementを取得
ToolbarZoneRightAlign ツールバーの右のVisualElementを取得
CustomToolbar.cs
/// <summary>
/// ツールバーに描画ハンドラーの追加処理
/// </summary>
/// <param name="toolbar">描画されているツールバー</param>
static void AddHandler(object toolbar)
{
    FieldInfo root = toolbar.GetType().GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
    VisualElement concreteRoot = root.GetValue(toolbar) as VisualElement;
    // 左に表示
    VisualElement toolbarZone = concreteRoot.Q("ToolbarZoneLeftAlign");
    VisualElement parent = new VisualElement()
    {
        name = "ボタン名",
        tooltip = "ボタンの説明",
        style = {
                    flexGrow = 1,
                    flexDirection = FlexDirection.RowReverse,
                }
    };
    IMGUIContainer container = new IMGUIContainer();
    container.onGUIHandler += OnToolbarGUI;
    parent.Add(container);
    toolbarZone.Add(parent);
}
/// <summary>
/// ツールバー更新処理
/// </summary>
static void OnToolbarGUI()
{
    using (new GUILayout.HorizontalScope())
    {
        if (GUILayout.Button(EditorGUIUtility.IconContent("UnityEditor.GameView"),
                new GUIStyle("Command")
                {
                    fontSize = 16,
                    alignment = TextAnchor.MiddleCenter,
                    imagePosition = ImagePosition.ImageAbove,
                    fontStyle = FontStyle.Bold
                }
        ))
        {
            //ボタンを押されたときの処理
        }
    }
}

描画結果

描画の結果として、以下のように表示されます。
ボタンを押すと登録された処理が実行されます。
スクリーンショット 2023-12-05 18.01.43.png

UI Toolkitのデバッグを行う方法

Unityのツールバーにある「Window -> UI Toolkit -> Debugger」からデバッグ用の画面を開くことができます。
スクリーンショット 2023-12-06 19.33.25.png

UI Toolkit Debuggerのタブの下にあるプルダウンから、「Toolbar」や「SceneView」を選ぶことでどのような表示や値の確認、設定を変更しての見え方の調整が行なえます。
こちらを駆使することで理想的なUIを作成しましょう!

まとめ

2021年の記事の内容を改修する形で記載致しましたが、UI Toolkitにはまだまだやれることが多いため、新しいUIを設定する際やNode Graphの作成をする際に触ってみてください。
きっと楽しく、便利になると思います!
ありがとうございました。

それでは、次回は@FW14Bさんの記事です。
お楽しみに!

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3