UnityのUI ToolkitでMultiColumnListViewを使ってマルチカラムのリストビューを実装する方法をまとめました。
Unity 2022.2.17
はじめに
UI ToolkitのListView
を使うと、下図のような複数のカラムを持ったリストビューを作成することができます。
本記事ではこのようなマルチカラムのリストビューを持ったEditorWindowの作り方についてまとめます。
UXMLファイルを作成する
まずUXMLファイルでレイアウトを作成します。
以下のようにMultiColumnListView
と、その中に二つのカラムを設定します。
<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:MultiColumnListView fixed-item-height="20"> <ui:Columns> <ui:Column name="name" title="Name" width="80" /> <ui:Column name="description" title="Description" width="80" /> </ui:Columns> </ui:MultiColumnListView> </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<Item> _items = new(); private void Reset() { for (var i = 0; i < 100; i++) _items.Add(new Item { name = $"Item {i}", description = $"Description {i}" }); } private void CreateGUI() { editorLayout.CloneTree(rootVisualElement); var multiColumnListView = rootVisualElement.Q<MultiColumnListView>(); // itemsSourceにソースとなるリストを代入 multiColumnListView.itemsSource = _items; var nameColumn = multiColumnListView.columns["name"]; var descriptionColumn = multiColumnListView.columns["description"]; // セルのレイアウトを作成する処理 nameColumn.makeCell = labelItemLayout.CloneTree; descriptionColumn.makeCell = labelItemLayout.CloneTree; // セルの内容を設定する処理 nameColumn.bindCell = (e, i) => e.Q<Label>().text = _items[i].name; descriptionColumn.bindCell = (e, i) => e.Q<Label>().text = _items[i].description; } [MenuItem("Window/Example")] public static void ShowWindow() { GetWindow<Example>(); } [Serializable] public struct Item { public string name; public string description; } }
説明はコメントに書いた通りです。
各セルに対してレイアウトを生成し、セルの内容をバインドできます。
実行結果
前節のスクリプトのInspectorからeditorLayout
にeditor_layout.uxml
を、labelItemLayout
にitem_layout.uxml
をアサインし、Window > Exampleからウィンドウを開くと以下の結果が得られます。
正常に実装できていることを確認できました。