Version: 2021.3
言語: 日本語
UI Toolkit について
カスタムインスペクターの作成

UI Toolkit のシンプルなワークフロー

特定の作業を頻繁に行う場合、UI Toolkit を使ってその作業専用の UI を作成することができます。例えば、カスタムのエディターウィンドウを作成することができます。

このガイドでは、カスタムエディターウィンドウを例として、UI Toolkit の基本的なワークフローを説明します。UI Builder、UXML、C# スクリプトを使用して、カスタムエディターウィンドウを作成し、UI コントロールをカスタムエディ ターウィンドウに追加する方法を説明します。

この例で作成するすべてのファイルは、GitHub リポジトリ にあります。

要件

このガイドは、Unity エディターと C# スクリプトを使い慣れていて、UI Toolkit を初めて使う開発者のためのものです。以下の概念について基本的な知識があることが推奨されます。

カスタムエディターウィンドウの作成

  1. Project ウィンドウで右クリックし、Create > UI Toolkit > Editor Window を選択します。
  2. UI Toolkit Editor Window Creator で MyCustomEditor と入力し、USS* を無効にします。
  3. Continue をクリックします。

これにより、2 つのラベルを持つカスタムのエディターウィンドウが作成されます。エディターウィンドウはメニューから開くことができます (Window > UI Toolkit > MyCustomEditor)。ソースファイルは Asset/Editor フォルダーにあります。

UI コントロールをウィンドウに加える

以下の方法で UI コントロールをウィンドウに加えることができます。

これらの方法は、個別でも、組み合わでも使用することもできます。以下の例では、これらのメソッドを組み合わせて、3 組のラベル、ボタン、トグルを作成します。

UI Builder を使用して UI コントロールを加える

UI コントロールをウィンドウに視覚的に加えるには、UI Builder を使用します。以下の例は、デフォルトのラベルに加えて、ボタンとトグルをカスタムエディターウィンドウに加える方法を示しています。

  1. Editor フォルダーで、MyCustomEditor.uxml をダブルクリックして、UI Builder を開きます。

  2. UI Builder で、Button と Toggle を Library > Controls から Hierarchy または **Viewport のウィンドウプレビューにドラッグしてください。

  3. Hierarchy で、コントロールにいくつかの属性を加えます。

    • ラベルをクリックし、Inspector の Text フィールドで、デフォルトテキストを These controls were created in UI Builder に変更します。
    • ボタンをクリックし、Inspector の Text フィールドに This is button1 と入力します。Inspector の Name フィールドに button1 と入力します。
    • トグルをクリックし、Inspector の Label フィールドに Number? と入力します。Inspector の Name フィールドに toggle1 と入力します。
  4. 保存 して UI Builder ウィンドウを閉じます。

  5. カスタムエディターウィンドウを開きます。ウィンドウ内に追加したボタンとトグルが表示されます。

UI コントロールが一式揃ったカスタムエディターウィンドウ
UI コントロールが一式揃ったカスタムエディターウィンドウ

UXML を使用して UI コントロールを加える

テキストファイルで UI を定義したい場合は、UXML を編集して UI コントロールを追加できます。この例では、もう一揃いのラベル、ボタン、トグルをウィンドウに追加します。

  1. Editor フォルダーで、Assets > Create > UI Toolkit > UI Document をクリックして、MyCustomEditor_UXML.uxml という UXML ファイルを作成します。

  2. テキストエディターで MyCustomEditor_UXML.uxml を開きます。

    ヒント: Project ウィンドウの MyCustomEditor_UXML.uxml の矢印をクリックし、inlineStyle をダブルクリックすると、それを実行できます。

  3. デフォルトでは、UXML 文書には engine:UXML タグが付いた 1 つの要素が表示されます。これは、XML ツリーのルート要素です。この要素の中に、UI コントロールとその属性を加えます。

    完成した MyCustomEditor_UXML.uxml ファイルは、以下のようになります。

    <?xml version="1.0" encoding="utf-8"?>
    <engine:UXML
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:engine="UnityEngine.UIElements"
        xmlns:editor="UnityEditor.UIElements"
        xsi:noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd"
    >
        <engine:Label text="These controls were created with UXML." />
        <engine:Button text="This is button2." name="button2"/>
        <engine:Toggle label="Number?" name="toggle2"/>
    </engine:UXML>
    
  4. MyCustomEditor.cs を開きます。

  5. MyCustomEditor クラスに m_UXMLTree という名の private の VisualTreeAsset フィールドを追加します。その上に [SerializeField] という属性を付けます。

    [SerializeField]
    private VisualTreeAsset m_UXMLTree;
    
  6. CreateGUI() の末尾に以下のコードを追加します。

    rootVisualElement.Add(m_UXMLTree.Instantiate());
    
  7. Project ウィンドウで MyCustomEditor.cs を選択します。

  8. MyCustomEditor_UXML.uxml を Project ウィンドウから Inspector の UXML Tree フィールドにドラッグします。これで、UXML がビジュアルツリーに割り当てられます。

  9. カスタムエディターウィンドウを開きます。3 つのラベル、2 つのボタン、2 つのトグルがウィンドウに表示されているはずです。

2 揃いの UI コントロールを持つカスタムエディターウィンドウ
2 揃いの UI コントロールを持つカスタムエディターウィンドウ

C# スクリプトを使用して UI コントロールを加える

コーディングを使いたい場合は、C# スクリプトでウィンドウに UI コントロールを加えられます。この例では、もう一揃いのラベル、ボタン、トグルをウィンドウに追加します。

  1. MyCustomEditor.cs を開きます。

  2. Unity では、ラベル、ボタン、トグルなどの基本的な UI コントロールに UnityEngine.UIElements を使用します。UI コントロールを使用するには、(まだ存在しない場合は) 以下の宣言を加える必要があります。

    using UnityEngine.UIElements;
    
  3. 既存のラベルのテキストを "Hello World!From C#" から "These controls were created using C# code." に変えます。

  4. EditorWindow クラスには rootVisualElement と呼ばれるプロパティがあります。UI コントロールをウィンドウに追加するには、まず、いくつかの属性を持つ要素クラスをインスタンス化し、rootVisualElement の Add メソッドを使用します。

    完成した CreateGUI() メソッドは、以下のようになります。

    public void CreateGUI()
    {
        // 各エディターウィンドウは、ルート VisualElement オブジェクトを含んでいます。
        VisualElement root = rootVisualElement;
    
        // VisualElement オブジェクトは、ツリー階層に従って他の VisualElement を持つことができます。
        Label label = new Label("These controls were created using C# code.");
        root.Add(label);
    
        Button button = new Button();
        button.name = "button3";
        button.text = "This is button3.";
        rootVisualElement.Add(button);
    
        Toggle toggle = new Toggle();
        toggle.name = "toggle3";
        toggle.label = "Number?";
        rootVisualElement.Add(toggle);
    
        // UXML をインポートします
        var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/MyCustomEditor.uxml");
        VisualElement labelFromUXML = visualTree.Instantiate();
        root.Add(labelFromUXML);
    
        rootVisualElement.Add(m_UXMLTree.Instantiate());
    }
    
  5. エディターに移動して、カスタムエディターウィンドウを開きます。3 つのラベル、3 つのボタン、3 つのトグルがウィンドウに表示されているはずです。

3 揃いのコントロールを持つカスタムエディターウィンドウ
3 揃いのコントロールを持つカスタムエディターウィンドウ

UI コントロールの動作を定義する

UI コントロールにイベントハンドラーを設定すると、ボタンをクリックしたときや、トグルを選択/クリアしたときに、UI コントロールが何らかのタスクを実行します。

下のコードでは、以下の処理を行うイベントハンドラーの例を示しています。

  • ボタンをクリックすると、エディターコンソールにメッセージが表示されます。
  • トグルを選択すると、ボタンが何回クリックされたかがコンソールに表示されます。
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class MyCustomEditor : EditorWindow
{
    [MenuItem("Window/UI Toolkit/MyCustomEditor")]
    public static void ShowExample()
    {
        MyCustomEditor wnd = GetWindow<MyCustomEditor>();
        wnd.titleContent = new GUIContent("MyCustomEditor");
    }

    [SerializeField]
    private VisualTreeAsset m_UXMLTree;

    private int m_ClickCount = 0;

    private const string m_ButtonPrefix = "button";

    public void CreateGUI()
    {
        // 各エディターウィンドウは、ルート VisualElement オブジェクトを含みます。
        VisualElement root = rootVisualElement;

        // VisualElement オブジェクトは、ツリー階層に従って他の VisualElement を持つことができます。
        Label label = new Label("These controls were created using C# code.");
        root.Add(label);

        Button button = new Button();
        button.name = "button3";
        button.text = "This is button3.";
        rootVisualElement.Add(button);

        Toggle toggle = new Toggle();
        toggle.name = "toggle3";
        toggle.label = "Number?";
        rootVisualElement.Add(toggle);

         // UXML をインポートします
        var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/MyCustomEditor.uxml");
        VisualElement labelFromUXML = visualTree.Instantiate();
        root.Add(labelFromUXML);

        rootVisualElement.Add(m_UXMLTree.Instantiate());

         //イベントハンドラーを呼び出します
        SetupButtonHandler();
    }

     //ボタンクリックと回数を数えるイベントハンドラーの関数 
    private void SetupButtonHandler()
    {
        var buttons = rootVisualElement.Query<Button>();
        buttons.ForEach(RegisterHandler);
    

    private void RegisterHandler(Button button)
    {
        button.RegisterCallback<ClickEvent>(PrintClickMessage)</ClickEvent>を実行します。<ClickEvent>
    }

    private void PrintClickMessage(ClickEvent evt)
    {
        ++m_ClickCount;

        //ボタンやトグルに名前をつけたので、
        //ボタンにつけた名前を使ってトグルの名前を見つけることができます。
        Button button = evt.currentTarget as Button;
        string buttonNumber = button.name.Substring(m_ButtonPrefix.Length);
        string toggleName = "toggle" + buttonNumber;
        Toggle toggle = rootVisualElement.Q<Toggle>(toggleName);

        Debug.Log("Button was clicked!" +
            (toggle.value ? " Count: " + m_ClickCount : ""));
    }
}

その他の参考資料

UI Toolkit について
カスタムインスペクターの作成