Повторное использование файлов UXML
Вы можете создать файл UXML в качестве шаблона и повторно использовать его в других файлах UXML.
Импорт шаблона UXML
Проектируя большой интерфейс, вы можете создавать UXML-шаблоны для отдельных его частей и использовать <Template> и <Instance> элементов для импорта в другой файл UXML.
Например, если у вас есть портретный элемент UI, содержащий изображение, имя и метку, вы можете создать файл шаблона UXML как Portrait.uxml со следующим содержимым:
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<ui:VisualElement class="portrait">
<ui:Image name="portraitImage" style="--unity-image: url(a.png)"/>
<ui:Label name="nameLabel" text="Name"/>
<ui:Label name="levelLabel" text="42"/>
</ui:VisualElement>
</ui:UXML>
Затем вы можете повторно использовать шаблон Портрет, как показано ниже:
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<ui:Template src="Portrait.uxml" name="Portrait"/>
<ui:VisualElement name="players">
<ui:Instance template="Portrait" name="player1"/>
<ui:Instance template="Portrait" name="player2"/>
</ui:VisualElement>
</ui:UXML>
Переопределение атрибутов UXML
Создавая экземпляры UXML-шаблона, вы можете переопределить значения атрибутов его элементов по умолчанию. Благодаря переопределениям атрибутов один и тот же шаблон можно многократно инстанцировать с разными значениями.
Переопределение атрибута
Атрибуты можно переопределять с помощью UXML тег. Чтобы переопределить атрибут, укажите следующее:
-
element-nameатрибут элемента, атрибуты которого вы хотите переопределить - Имя переопределяемого атрибута
- Новое значение атрибута
Например, если вы хотите отображать одинаковые данные для каждого игрока в вашей игре, вы можете создать шаблон UXML и использовать переопределения атрибутов для создания экземпляров для каждого игрока.
Сначала создайте шаблон, например PlayerTemplate.uxml, со следующим содержанием:
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<ui:Label name="player-name-label" text="default name" />
<ui:Label name="player-score-label" text="default score" />
</ui:UXML>
Затем создайте его экземпляр из другого файла UXML и переопределите атрибуты, чтобы вывести имя и счёт каждого игрока:
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<ui:Template src="PlayerTemplate.uxml" name="PlayerTemplate" />
<ui:Instance name="player1" template="PlayerTemplate">
<!-- Alice is the new value of the text attribute for the player-name-label -->
<ui:AttributeOverrides element-name="player-name-label" text="Alice" />
<!-- 2 is the new value of the text attribute for the player-score-label -->
<ui:AttributeOverrides element-name="player-score-label" text="2" />
</ui:Instance>
<ui:Instance name="player2" template="PlayerTemplate">
<!-- Bob is the new value of the text attribute for the player-name-label -->
<ui:AttributeOverrides element-name="player-name-label" text="Bob" />
<!-- 1 is the new value of the text attribute for the player-score-label -->
<ui:AttributeOverrides element-name="player-score-label" text="1" />
</ui:Instance>
</ui:UXML>
Переопределить несколько атрибутов
В одном переопределении можно указать несколько атрибутов. Например, следующая запись находит в экземпляре любой элемент с именем player-name-label, и
- Переопределяет значение по умолчанию атрибута
textновым значениемAlice. - Переопределяет значение по умолчанию атрибута
tooltipновым значениемTooltip 1.
<ui:AttributeOverrides element-name="player-name-label" text="Alice" tooltip="Tooltip 1" />
Переопределения атрибутов гнезда
Переопределения атрибутов распространяются по вложенным шаблонам в иерархии элементов. Например, если шаблон A создаёт экземпляр шаблона B, а шаблон B — экземпляр шаблона C, то и шаблон A, и шаблон B могут переопределять атрибуты в шаблоне C.
При переопределении атрибутов во вложенных шаблонах приоритет имеет самое внешнее переопределение. В предыдущем примере, если шаблон A и шаблон B переопределяют один и тот же атрибут шаблона C, в отрисованном интерфейсе окажется значение из шаблона A.
Переопределение стилей экземпляров шаблона
Если вы создаете экземпляры шаблона UXML, и элемент в шаблоне имеет встроенный стиль, определенный с помощью style атрибут, вы не можете использовать AttributeOverrides чтобы переопределить это style атрибут. Однако вы можете использовать селекторы USS в таблице стилей, чтобы переопределить оформление экземпляров вашего шаблона.
Например, если у вас есть следующий шаблон UXML под названием Hotkeys.uxml, который определяет #Container с двумя метками, а #Container имеет встроенный стиль, определяющий направление строки flex:
<ui:UXML xmlns:ui="UnityEngine.UIElements" >
<ui:VisualElement name="Container" style="flex-direction: row;">
<ui:Label text="E" name="Hotkeys" />
<ui:Label text="Talk" name="Action" />
</ui:VisualElement>
</ui:UXML>
Если вы хотите создать два экземпляра шаблона, второй из которых имеет обратное направление строки Flex, вы не можете использовать AttributeOverides чтобы переопределить style атрибут #Container элемент в вашем втором экземпляре.
Чтобы переопределить оформление, сначала удалите встроенный style атрибут из #Container элемент в файле шаблона UXML. Встроенные стили имеют приоритет над стилями USS, поэтому удаление их позволяет применять правила USS.
Затем, в файле UXML, где вы создаете экземпляры шаблона, присвоите уникальные имена каждому экземпляру (например, Hotkeys и ReversedHotkeys). Ссылайтесь на таблицу стилей USS (например, ContextHotKeys.uss) в этом файле:
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<ui:Template name="Hotkeys" src="Hotkeys.uxml"/>
<Style src="ContextHotKeys.uss"/>
<ui:Instance template="Hotkeys" name="Hotkeys" />
<ui:Instance template="Hotkeys" name="ReversedHotkeys" />
</ui:UXML>
Затем в файле таблицы стилей ContextHotKeys.ussвы можете использовать имя экземпляра в качестве селекторов для нацеливания элемента #Container в каждом экземпляре. Это позволяет применять различные стили к каждому экземпляру по мере необходимости.
#ReversedHotkeys > #Container {
flex-direction: row-reverse;
}
#Hotkeys > #Container {
flex-direction: row;
}
Ограничения
Переопределения атрибутов имеют следующие ограничения:
- Переопределения атрибутов находят соответствующие атрибуты в соответствии с именем элемента, которое вы указываете. USS Селекторы или UQuery чтобы соответствовать элементам.
- Хотя вы можете переопределить у элемента
binding-pathатрибут, привязка данных не работает с переопределениями атрибутов. - Вы не можете переопределить у элемента
class,name, илиstyleатрибуты.
Указать, где вставлять дочерние элементы в шаблоне UXML
Вы можете использовать атрибут content-container визуального элемента, чтобы указать, где вставлять дочерние элементы в шаблоне UXML. Например, если у вас есть следующий файл шаблона UXML как MyTemplate.uxml:
<ui:UXML xmlns:ui="UnityEngine.UIElements" >
<ui:Label text="Group Title" name="groupTitle" />
<ui:VisualElement name="parent-container" content-container="anyValue">
<!--Add child elements here -->
</ui:VisualElement>
<ui:VisualElement />
</ui:UXML>
Затем вы можете применить шаблон с вложенными дочерними элементами следующим образом:
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<ui:Template src="MyTemplate.uxml" name="my-template"/>
<ui:Instance template="my-template">
<ui:Label text="Test"/> <!--This label element is instantiated inside the `parent-container` element-->
</ui:Instance>
</ui:UXML>
Примечание:
- Для атрибута
content-containerможно указать любое строковое значение. - Определяйте только один элемент с атрибутом
content-containerв шаблоне UXML. Если у нескольких элементов есть этот атрибут, это создает неопределенность для системы. В таких случаях дочерние элементы вставляются в первый элемент, имеющий атрибутcontent-container, во время прохождения визуального дерева с глубиной в первую очередь. Чтобы обеспечить предсказуемое поведение, определяйтеcontent-containerтолько для одного элемента в вашем шаблоне.