リストビューとツリービューは、UI デザインにおけるよく使用される機能です。UI Toolkit を使用すると、カスタムエディターウィンドウで、またはランタイム時にリストビューとツリービューを作成できます。この例では、カスタムエディターウィンドウ内にリストビューとツリービューを作成する方法を紹介します。リストとツリーの構造を UXML で設定し、C# スクリプトで動的に入力します。
この例では以下を表示する 4 つのエディターウィンドウを作成します。
この例で作成するすべてのファイルは、GitHub リポジトリ にあります。
このガイドは、Unity エディター、UI Toolkit、および C# スクリプトに精通している開発者を対象としています。始める前に、以下をよく理解してください。
2 つの惑星のグループとツリービューのルートノードで構成される C# スクリプトでデータを作成します。
Unity で任意のテンプレートでプロジェクトを作成します。
Project ウィンドウに、Editor
という名前のフォルダーを作成します。
Editor
フォルダーに、PlanetsWindow.cs
という名前の C# スクリプトを作成します。
PlanetsWindow.cs
のコンテンツを以下のように置き換えてください。
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UIElements;
// Base class for all windows that display planet information.
public class PlanetsWindow : EditorWindow
{
[SerializeField]
protected VisualTreeAsset uxml;
// Nested interface that can be either a single planet or a group of planets.
protected interface IPlanetOrGroup
{
public string name
{
get;
}
public bool populated
{
get;
}
}
// Nested class that represents a planet.
protected class Planet : IPlanetOrGroup
{
public string name
{
get;
}
public bool populated
{
get;
}
public Planet(string name, bool populated = false)
{
this.name = name;
this.populated = populated;
}
}
// Nested class that represents a group of planets.
protected class PlanetGroup : IPlanetOrGroup
{
public string name
{
get;
}
public bool populated
{
get
{
var anyPlanetPopulated = false;
foreach (Planet planet in planets)
{
anyPlanetPopulated = anyPlanetPopulated || planet.populated;
}
return anyPlanetPopulated;
}
}
public readonly IReadOnlyList<Planet> planets;
public PlanetGroup(string name, IReadOnlyList<Planet> planets)
{
this.name = name;
this.planets = planets;
}
}
// Data about planets in our solar system.
protected static readonly List<PlanetGroup> planetGroups = new List<PlanetGroup>
{
new PlanetGroup("Inner Planets", new List<Planet>
{
new Planet("Mercury"),
new Planet("Venus"),
new Planet("Earth", true),
new Planet("Mars")
}),
new PlanetGroup("Outer Planets", new List<Planet>
{
new Planet("Jupiter"),
new Planet("Saturn"),
new Planet("Uranus"),
new Planet("Neptune")
})
};
// Expresses planet data as a list of the planets themselves. Needed for ListView and MultiColumnListView.
protected static List<Planet> planets
{
get
{
var retVal = new List<Planet>(8);
foreach (var group in planetGroups)
{
retVal.AddRange(group.planets);
}
return retVal;
}
}
// Expresses planet data as a list of TreeViewItemData objects. Needed for TreeView and MultiColumnTreeView.
protected static IList<TreeViewItemData<IPlanetOrGroup>> treeRoots
{
get
{
int id = 0;
var roots = new List<TreeViewItemData<IPlanetOrGroup>>(planetGroups.Count);
foreach (var group in planetGroups)
{
var planetsInGroup = new List<TreeViewItemData<IPlanetOrGroup>>(group.planets.Count);
foreach (var planet in group.planets)
{
planetsInGroup.Add(new TreeViewItemData<IPlanetOrGroup>(id++, planet));
}
roots.Add(new TreeViewItemData<IPlanetOrGroup>(id++, group, planetsInGroup));
}
return roots;
}
}
}
リストビューを作成するには、まず UI Builder を使って ListView UI コントロールを作成します。次に、ListView でカスタムエディターウィンドウを作成し、C# スクリプトでリストのデータを取得する場所を定義します。最後に、UXML ファイルを C# スクリプトに参照します。
Editor
フォルダーを右クリックします。
Create > UI Toolkit > Editor Window を選択します。
C# ボックスに PlanetsListView
と入力し、USS チェックボックスをオフにします。これで 2 つのファイル PlanetsListView.uxml
とPlanetsListView.cs
が作成されます。
PlanetsListView.uxml
をダブルクリックして、UI Builder で開きます。
Hierarchy ウィンドウで Label コントロールを削除し、ListView コントロールを追加します。
Hierarchy ウィンドウで ListView 選択します。
Inspector ウィンドウで、Fixed Item Height を 20 に設定します。
変更を保存します。PlanetsListView.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:ListView fixed-item-height="20" />
</ui:UXML>
PlanetsListView.cs
の内容を以下のように置き換えます。
using UnityEditor;
using UnityEngine.UIElements;
public class PlanetsListView : PlanetsWindow
{
[MenuItem("Planets/Standard List")]
static void Summon()
{
GetWindow<PlanetsListView>("Standard Planet List");
}
void CreateGUI()
{
uxml.CloneTree(rootVisualElement);
var listView = rootVisualElement.Q<ListView>();
// Set ListView.itemsSource to populate the data in the list.
listView.itemsSource = planets;
// Set ListView.makeItem to initialize each entry in the list.
listView.makeItem = () => new Label();
// Set ListView.bindItem to bind an initialized entry to a data item.
listView.bindItem = (VisualElement element, int index) =>
(element as Label).text = planets[index].name;
}
}
Unity の Project ウィンドウで PlanetsListView.cs
を選択し、Inspector の Uxml フィールドに PlanetsListView.uxml
をドラッグします。
メニューから Planets > Standard List を選択すると、惑星のリストが表示されます。
複数の列を持つリストビューを作成するには、まず MultiColumnListView UI コントロールを作成し、UXML ファイルで列の数と列のタイトルを定義します。次に、MultiColumnListView でカスタムエディターウィンドウを作成し、C# スクリプトで各列のリストのデータを取得する場所を定義します。最後に、UXML ファイルを C# スクリプトに参照します。
Editor
フォルダーを右クリックします。
**Create** > **UI Toolkit** > **UI Document** の順に選択して UXML ファイルを作成し、
PlanetsMultiColumnListView.uxml` と名付けます。
テキストエディターで PlanetsMultiColumnListView.uxml
を開きます。
PlanetsMultiColumnListView.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:MultiColumnListView fixed-item-height="20">
<!-- Columns and Column aren't Visual Elements or controls. They are considered attributes of MultiColumnListView. -->
<ui:Columns>
<ui:Column name="name" title="Name" width="80" />
<ui:Column name="populated" title="Populated?" width="80" />
</ui:Columns>
</ui:MultiColumnListView>
</ui:UXML>
Editor
フォルダーに、PlanetsMultiColumnListView.cs
という名前の C# スクリプトを作成します。
PlanetsMultiColumnListView.cs
の内容を以下のように置き換えます。
using UnityEditor;
using UnityEngine.UIElements;
public class PlanetsMultiColumnListView : PlanetsWindow
{
[MenuItem("Planets/Multicolumn List")]
static void Summon()
{
GetWindow<PlanetsMultiColumnListView>("Multicolumn Planet List");
}
void CreateGUI()
{
uxml.CloneTree(rootVisualElement);
var listView = rootVisualElement.Q<MultiColumnListView>();
// Set MultiColumnListView.itemsSource to populate the data in the list.
listView.itemsSource = planets;
// For each column, set Column.makeCell to initialize each cell in the column.
// You can index the columns array with names or numerical indices.
listView.columns["name"].makeCell = () => new Label();
listView.columns["populated"].makeCell = () => new Toggle();
// For each column, set Column.bindCell to bind an initialized cell to a data item.
listView.columns["name"].bindCell = (VisualElement element, int index) =>
(element as Label).text = planets[index].name;
listView.columns["populated"].bindCell = (VisualElement element, int index) =>
(element as Toggle).value = planets[index].populated;
}
}
Unity の Project ウィンドウで PlanetsMultiColumnListView.cs
を選択します。
Inspector の Uxml フィールドに PlanetsMultiColumnListView.uxml
をドラッグします。
メニューから Planets > Multicolumn List を選択すると、2 列のリストが表示されます。1 つの列には惑星のリストがあります。 もう 1 つの列には、惑星に人が住んでいるかどうかを示すトグルがあります。
カスタムエディターでツリービューを作成するには、まず TreeView UI コントロールを UXML ファイルに作成します。次に、TreeView でカスタムエディターウィンドウを作成して、どこで C# スクリプトでMultiColumnListView でカスタムエディターウィンドウを作成し、C# スクリプトで、ツリーノードのデータを取得する場所を定義します。最後に、UXML ファイルを C# スクリプトに参照します。
Editor
フォルダーに UXML ファイルを作成し、PlanetsTreeView.uxml
と名付けます。
PlanetsTreeView.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:TreeView fixed-item-height="20" />
</ui:UXML>
Editor
フォルダーに PlanetsTreeView.cs
という名前の C# ファイルを作成します。
PlanetsTreeView.cs
の内容を以下のように置き換えます。
using UnityEditor;
using UnityEngine.UIElements;
public class PlanetsTreeView : PlanetsWindow
{
[MenuItem("Planets/Standard Tree")]
static void Summon()
{
GetWindow<PlanetsTreeView>("Standard Planet Tree");
}
void CreateGUI()
{
uxml.CloneTree(rootVisualElement);
var treeView = rootVisualElement.Q<TreeView>();
// Call TreeView.SetRootItems() to populate the data in the tree.
treeView.SetRootItems(treeRoots);
// Set TreeView.makeItem to initialize each node in the tree.
treeView.makeItem = () => new Label();
// Set TreeView.bindItem to bind an initialized node to a data item.
treeView.bindItem = (VisualElement element, int index) =>
(element as Label).text = treeView.GetItemDataForIndex<IPlanetOrGroup>(index).name;
}
}
Unity の Project ウィンドウで PlanetsTreeView.cs
を選択します。
Inspector の Uxml フィールドに PlanetsTreeView.uxml
をドラッグします。
メニューから Planets > Standard Tree を選択すると、ノードでグループ化された 2 つの惑星リストが表示されます。各ノードの横には小さな矢印があります。矢印を選択すると、ウィンドウにグループの惑星が表示されます。
カスタムエディターで複数の列を持つツリービューを作成するには、まず TreeView UI コントロールを UXML ファイルに作成します。次に、MultiColumnTreeView でカスタムエディターウィンドウを作成して、どこで C# スクリプトでMultiColumnListView でカスタムエディターウィンドウを作成し、C# スクリプトでツリーノードのデータを取得する場所を定義します。最後に、UXML ファイルを C# スクリプトに参照します。
Editor
フォルダーに UXML ファイルを作成し、PlanetsMultiColumnTreeView.uxml
と名付けます。
PlanetsMultiColumnTreeView.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:MultiColumnTreeView fixed-item-height="20">
<!-- Columns and Column aren't Visual Elements or controls; they are considered attributes of MultiColumnListView. -->
<ui:Columns>
<ui:Column name="name" title="Name" width="120" />
<ui:Column name="populated" title="Populated?" width="80" />
</ui:Columns>
</ui:MultiColumnTreeView>
</ui:UXML>
Editor
フォルダーに PlanetsMultiColumnTreeView.cs
という C# ファイルを作成します。
PlanetsMultiColumnTreeView.cs
の内容を以下のように置き換えます。
using UnityEditor;
using UnityEngine.UIElements;
public class PlanetsMultiColumnTreeView : PlanetsWindow
{
[MenuItem("Planets/Multicolumn Tree")]
static void Summon()
{
GetWindow<PlanetsMultiColumnTreeView>("Multicolumn Planet Tree");
}
void CreateGUI()
{
uxml.CloneTree(rootVisualElement);
var treeView = rootVisualElement.Q<MultiColumnTreeView>();
// Call MultiColumnTreeView.SetRootItems() to populate the data in the tree.
treeView.SetRootItems(treeRoots);
// For each column, set Column.makeCell to initialize each node in the tree.
// You can index the columns array with names or numerical indices.
treeView.columns["name"].makeCell = () => new Label();
treeView.columns["populated"].makeCell = () => new Toggle();
// For each column, set Column.bindCell to bind an initialized node to a data item.
treeView.columns["name"].bindCell = (VisualElement element, int index) =>
(element as Label).text = treeView.GetItemDataForIndex<IPlanetOrGroup>(index).name;
treeView.columns["populated"].bindCell = (VisualElement element, int index) =>
(element as Toggle).value = treeView.GetItemDataForIndex<IPlanetOrGroup>(index).populated;
}
}
Unity の Project ウィンドウで PlanetsMultiColumnTreeView.cs
を選択します。
Inspector の Uxml フィールドに PlanetsMultiColumnTreeView.uxml
をドラッグします。
Planets > Multicolumn Tree を選択すると、2 列のリストが表示されます。最初の列には、ノードでグループ化された惑星のリストが 2 つあります。各ノードの横には矢印があります。矢印を選択すると、ウィンドウにそのグループの惑星とトグルのリストが表示されます。