UnityのUI ToolkitでMultiColumnTreeViewを使ってマルチカラムのツリービューを実装する方法についてまとめました。
Unity 2022.2.17
はじめに
UI ToolkitのMutiColumnTreeView
を使うと、下図のようなマルチカラムのツリービューを作れます。
本記事ではこのようなマルチカラムツリービューを持ったEditorWindowの作り方についてまとめます。
なおシングルカラムのツリービューに関しては以下の記事で説明しています。
UXMLファイルを作成する
まずUXMLファイルでレイアウトを作成します。
以下のようにMultiColumnTreeView
と、その中に二つのカラムを設定します。
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False"> <ui:MultiColumnTreeView fixed-item-height="20"> <ui:Columns> <ui:Column name="name" title="Name" width="120" /> <ui:Column name="description" title="Description" width="200" /> </ui:Columns> </ui:MultiColumnTreeView> </ui:UXML>
これをeditor_layout.uxml
として保存しておきます。
次にリストに表示する各項目のレイアウトを作成します。
といっても今回は単純にラベルを表示しているだけです。
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False"> <ui:Label text="Label" /> </ui:UXML>
これをitem_layout.uxml
として保存しておきます。
EditorWindowを作成する
次に以下の通りEditorWindow
のスクリプトを作成します。
using System; using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEngine.UIElements; public sealed class Example : EditorWindow { [SerializeField] private VisualTreeAsset editorLayout; [SerializeField] private VisualTreeAsset labelItemLayout; private readonly List<TreeViewItemData<Item>> _rootItems = new(); private void Reset() { var id = 0; for (var i = 0; i < 10; i++) { // 子アイテムのリストを作成 var items = new List<TreeViewItemData<Item>>(10); for (var j = 0; j < 10; j++) { var item = new TreeViewItemData<Item>(id++, new Item { name = $"Item {j}", description = $"Description {j}" }); items.Add(item); } // ルートアイテムを作成し、子アイテムを追加 var rootItem = new TreeViewItemData<Item>(id++, new Item { name = $"Group {i}" }, items); // ルートアイテムのみをデータソースに追加 _rootItems.Add(rootItem); } } private void CreateGUI() { editorLayout.CloneTree(rootVisualElement); var multiColumnTreeView = rootVisualElement.Q<MultiColumnTreeView>(); // データソースを設定 multiColumnTreeView.SetRootItems(_rootItems); var nameColumn = multiColumnTreeView.columns["name"]; var descriptionColumn = multiColumnTreeView.columns["description"]; // セルのレイアウトを作成する処理 nameColumn.makeCell = labelItemLayout.CloneTree; descriptionColumn.makeCell = labelItemLayout.CloneTree; // セルの内容を設定する処理 nameColumn.bindCell = (e, i) => e.Q<Label>().text = multiColumnTreeView.GetItemDataForIndex<Item>(i).name; descriptionColumn.bindCell = (e, i) => e.Q<Label>().text = multiColumnTreeView.GetItemDataForIndex<Item>(i).description; } [MenuItem("Window/Example")] public static void ShowWindow() { GetWindow<Example>(); } [Serializable] public struct Item { public string name; public string description; } }
説明はコメントに書いた通りです。
各セルに対してレイアウトを生成し、セルの内容をバインドできます。
実行結果
Window > Exampleからウィンドウを開くと以下の結果が得られます。
正常に実装できていることを確認できました。