Создание представлений списка и дерева
Список и дерево представления являются общими особенностями в UI дизайн. Вы можете использовать UI Toolkit для создания списков и деревьев внутри пользовательского окна Редактора или времени выполнения. В этом примере показано, как создать списки и деревья внутри пользовательского окна Редактора. Вы настраиваете структуру списков и деревьев с помощью UXML и затем динамически заполнить их в вашем C# скрипта.
Примерный обзор
В этом примере создаются четыре окна Редактора, в которых отображаются следующие элементы:
- Список планет с одной колонкой
- Список планет с двумя колонками
- Деревянный вид планет
- Деревянный вид планет с двумя колонками
Вы можете найти завершенные файлы, созданные этим примером, в хранилище GitHub.
Предварительные условия
Это руководство предназначено для разработчиков, знакомых со скриптами Unity Editor, UI Toolkit и C#. Перед началом работы ознакомьтесь со следующим:
Создать данные в C#
Создайте данные в скрипте C#, который состоит из двух групп планет и корневых узлов для дерева представления.
Создайте проект в Unity с любым шаблоном.
В окне Project создайте папку
Editor.В папке
Editorсоздайте скрипт C# с именемPlanetsWindow.cs.-
Заменить содержимое
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 uxmlAsset; // 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 для создания элемента управления ListView UI. Затем создайте окно редактора с помощью ListView и определите, где получить данные для списка в скрипте C#. Наконец, сделайте ссылку на файл UXML в скрипте C#.
Щелкните правой кнопкой мыши папку
Editor.Выберите Создать > UI Toolkit > Окно редактора.
В поле C# введите
PlanetsListViewи снимите флажок USS. Это создаст два файла:PlanetsListView.uxmlиPlanetsListView.cs.Дважды щелкните
PlanetsListView.uxml, чтобы открыть его в UI Builder.В окне Hierarchy удалите контроль Label и добавьте контроль ListView.
Выберите ListView в окне Hierarchy.
В окне 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() { // The protected variable 'uxmlAsset' is a VisualTreeAsset defined in the parent // class PlanetsWindow. uxmlAsset.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 выберите
PlanetsListView.csв окне Project, а затем перетащитеPlanetsListView.uxmlв поле Uxml в Inspector.Из меню выберите Планеты > Стандартный список, чтобы увидеть список планет.
Создание представления списка с несколькими столбцами
Чтобы создать представление списка с несколькими столбцами, сначала создайте MultiColumnListView UI контроллер, и определите количество столбцов и названия столбцов в файле UXML. Затем создайте пользовательское окно Редактора с MultiColumnListView и определите, где получить данные для списка в каждом столбце в скрипте C#. Наконец, укажите ссылку на файл UXML в скрипте C#.
Щелкните правой кнопкой мыши папку
Editor.Выберите Создать > UI Toolkit > UI Документ, чтобы создать файл 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создайте файл C# с именемPlanetsMultiColumnListView.cs.-
Заменить содержимое
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() { // The protected variable 'uxmlAsset' is a VisualTreeAsset defined in the parent // class PlanetsWindow. uxmlAsset.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 выберите
PlanetsMultiColumnListView.csв окне Project.Перетащите
PlanetsMultiColumnListView.uxmlв поле Uxml в Inspector.Из меню выберите Планеты > Многосторонний Список, чтобы увидеть список из двух столбцов. Один столбец содержит список планет. Второй столбец имеет переключатели, которые указывают, населена ли планета.
Создание дерева представления
Чтобы создать дерево представления в пользовательском Редакторе, сначала создайте TreeView UI контроллер в файле UXML. Затем создайте пользовательское окно Редактора с TreeView и определите, где получить данные для узлов дерева скриптом 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создайте файл C# с именемPlanetsTreeView.cs.-
Заменить содержимое
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() { // The protected variable 'uxmlAsset' is a VisualTreeAsset defined in the parent // class PlanetsWindow. uxmlAsset.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 выберите
PlanetsTreeView.csв окне Project.Перетащите
PlanetsTreeView.uxmlв поле Uxml в Inspector.Из меню выберите Планеты > Стандартное Дерево, чтобы увидеть два списка планет, сгруппированных по узлам. Рядом с каждым узлом находится стрелка. Если вы выберете стрелку, окно покажет планеты в группе.
Создание дерева с несколькими столбцами
Чтобы создать деревообразное представление с несколькими столбцами в пользовательском Редакторе, сначала создайте MultiColumnTreeView UI контроллер и определите столбцы в файле UXML. Затем создайте пользовательское окно Редактора с MultiColumnTreeView и определите, где получить данные для каждого столбца в скрипте 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создайте файл C# с именемPlanetsMultiColumnTreeView.cs.-
Заменить содержимое
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() { // The protected variable 'uxmlAsset' is a VisualTreeAsset defined in the parent // class PlanetsWindow. uxmlAsset.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 выберите
PlanetsMultiColumnTreeView.csв окне Project.Перетащите
PlanetsMultiColumnTreeView.uxmlв поле Uxml в Inspector.Выберите Планеты > Многостороннее Дерево, чтобы увидеть список с двумя столбцами. Первый столбец содержит два списка планет, сгруппированных по узлам. Рядом с каждым узлом находится стрелка. Если вы выберете стрелку, окно покажет список планет и переключателей в этой группе.