找回密码
 立即注册
查看: 357|回复: 0

Unity UIElement 一篇文章即可学会

[复制链接]
发表于 2022-8-28 09:17 | 显示全部楼层 |阅读模式
以下文档大部分参考官方手册,此处先奉上相关连接:UIElements Developer Guide
从新建窗口开始。

在【Project】视图,【Assets】目录下,找到或者新建【Editor】目录,右键【Editor】目录,依次选择【Create】-【UIElements】-【Editor Window】。打开如下创建窗口:


输入名字,点击【Confirm】。可得到三个文件,.cs .uxml .uss


三个文档的作用可理解为:
.uxml :预定义布局文档。
.uss :控件样式表
.cs :通过uxml和uss来拼UI
提供CS文件中的大致翻译便于理解:


UXML讲解

<?xml version="1.0" encoding="utf-8"?>
<UXML
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="UnityEngine.UIElements"
    xsi:noNamespaceSchemaLocation="../UIElementsSchema/UIElements.xsd"
    xsi:schemaLocation="UnityEngine.UIElements ../UIElementsSchema/UnityEngine.UIElements.xsd">


    <Label text="Select something to remove from your suitcase:"/>
    <Box>
        <Toggle name="boots" label="Boots" value="false" />
        <Toggle name="helmet" label="Helmet" value="false" />
        <Toggle name="cloak" label="Cloak of invisibility" value="false"/>
    </Box>
    <Box>
        <Button name="cancel" text="Cancel" />
        <Button name="ok" text="OK" />
    </Box>
</UXML>第一行为XML声明。声明是可选的,如果包含声明,则必须位于第一行开头。version是必须的,encoding是可选的。
<UXML>标签的属性:包括命名空间前缀定义(the namespace prefix definitions)和模式定义文件位置( the location of schema definition files),此处无顺序要求。
UIElements的元素都定义在命名空间:UnityEngine.UIElements 或者 UnityEditor.UIElements 中。
例如我们要使用元素Button,则需要指定:<UnityEngine.UIElements:Button />
为了方便,我们可以在<UXML>标签的属性中定义命名空间前缀,例如:xmlns:engine="UnityEngine.UIElements",这样我们就可以使用 <engine:Button />
为了更方便,我们可以定义默认命名空间。xmlns="UnityEngine.UIElements",元素Button的使用就可以更加简化:<Button />
元素基类:VisualElement

元素名字与C#中的类名一直,且VisualElement作为基类,提供如下公共属性:
name:名字,原则上保证名字是唯一的
picking-mode:有两个值:Position 响应鼠标操作,Ignore 忽略鼠标操作
tabindex:定义元素的 tabbing position
focusable:元素是否可聚焦(值类型为 boolean)
class:以空格分隔的标识符列表,用于表征元素。使用类将视觉样式分配给元素。您还可以使用类在 UQuery 中选择一组元素。
tooltip:鼠标悬停提示
view-data-key:一个字符串,它定义了用于元素序列化的键
UXML添加样式

可通过 <Style> ,在任何元素下引用样式表(stylesheet)
例如:
<engine:UXML ...>
    <engine:VisualElement class="root">
        <Style src="styles.uss" /> //此处是相对路径,需要styles.uss在同目录下
    </engine:VisualElement>
</engine:UXML>styles.uss文件:
#root {
    width: 200px;
    height: 200px;
    background-color: red;
}注意:<Style> 元素不能直接放到 <UXML> 节点下
也可以直接在元素的属性里面定义样式
<engine:UXML ...>
    <engine:VisualElement style="width: 200px; height: 200px; background-color: red;" />
</engine:UXML>重用UXML

您可以通过简单地在 UXML 文件中定义组件并使用另一个 UXML 文件中的<Template>和<Instance>元素将其导入来创建组件。
在设计大型用户界面时,您可以创建定义部分 UI 的模板 UXML 文件。
您可以在许多地方使用相同的 UI 定义。例如,假设您有一个包含图像、名称和标签的纵向 UI 元素。您可以创建一个 UXML 模板文件以在其他 UXML 文件中重用肖像 UI 元素。
例如,假设您在文件中有一个Portrait组件Assets/Portrait.uxml:
<engine:UXML ...>
    <engine:VisualElement class="portrait">
        <engine:Image name="portaitImage" style="--unity-image: url(\"a.png\")"/>
        <engine:Label name="nameLabel" text="Name"/>
        <engine:Label name="levelLabel" text="42"/>
    </engine:VisualElement>
</engine:UXML>您可以将Portrait组件嵌入到其他 UXML 模板中,如下所示:
<engine:UXML ...>
    <engine:Template src="/Assets/Portrait.uxml" name="Portrait"/>
    <engine:VisualElement name="players">
        <engine:Instance template="Portrait" name="player1"/>
        <engine:Instance template="Portrait" name="player2"/>
    </engine:VisualElement>
</engine:UXML>从 UXML 引用其他文件

UXML文件可通过元素引用其他UXML文件或者USS文件
<Template>和<Style>元素都接受“src”属性或“path”属性。
src属性:允许相对路径,在导入时提供错误消息(例如,文件丢失时),并确保 Unity 在播放器构建中正确包含您的 UXML 文件引用的资产。
该src属性要求文件路径相对于项目根目录或包含 UXML 文件的文件夹。您必须包含文件扩展名。在以下示例中,UXML 文件位于Assets\Editor\UXML,USS 文件位于Assets\Editor\USS。
根据 UXML 文件的位置,使用以下示例路径之一:src="../USS/styles.uss"或src="template.uxml"
根据项目的位置,使用以下示例之一作为绝对路径:src="/Assets/Editor/USS/styles.uss"或src="project:/Assets/Editor/UXML/template.uxml".
path属性:允许使用 Unity 资源机制,但在导入时不提供错误报告,并且不允许相对路径。
该path属性接受位于Resources文件夹或Editor Default Resources文件夹中的文件,具有以下规则:
如果文件位于Resources文件夹中,请不要包含文件扩展名。例如,写入path="template"位于Assets/Resources/template.uxml的文件。
如果文件位于Editor Default Resources文件夹中,则必须包含文件扩展名。例如,path="template.uxml"为位于Assets/Editor Default Resources/template.uxml的文件写入。
在C#中加载UXML

EditorWindow w = EditorWindow.GetWindow(typeof(MyWindow));
VisualTreeAsset uiAsset = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/MyWindow.uxml");
VisualElement ui = uiAsset.CloneTree();
w.rootVisualElement.Add(ui);在C#中查找元素

UQuery 提供了一组扩展方法,用于从任何 UIElements 可视树中检索元素。
UQuery 基于 JQuery 或 Linq,但 UQuery 旨在尽可能限制动态内存分配。这允许在移动平台上实现最佳性能。
要使用 UQuery 检索元素,请使用UQueryExtensions.Q 或 通过 UQueryExtensions.Query 初始化一个QueryBuilder。
例如,从根开始并找到第一个名称为foo的Button:
root.Query<Button>("foo").First();Unity提供的可使用布局元素

直接看官方手册就行:https://docs.unity3d.com/2019.4/Documentation/Manual/UIE-ElementRef.html
USS样式表

每个 VisualElement 都包含样式属性, 样式属性可以在 C# 中设置, 也可以在样式表中设置。 样式属性在其自己的数据结构(IStyle 接口)中重新分组。
UIElements 支持用 USS(Unity 样式表)编写的样式表。USS 文件是受 HTML 中的层叠样式表 (CSS) 启发的文本文件。USS 格式与 CSS 类似,但 USS 包括一些覆盖和自定义以便于更好地与 Unity 协同工作。
样式规则语法:
selector {
  property1:value;
  property2:value;
}样式与规则匹配:
定义样式表后,可以将其应用于 UIElements 视觉元素树。
在此过程中,选择器将与元素进行对比,从而解析从 USS 文件应用的属性。如果选择器与元素匹配,则样式声明将应用于元素。
例如,以下规则匹配任何 Button 对象:
Button {
  width: 200px;
}VisualElement 匹配
通过选择器规则进行匹配,主要支持以下四种匹配:
C# 类名(始终是派生层次最深的类,即派生到最末端的子类)
name 属性
class 集合
VisualElement 祖先和在视觉树中的位置
下面通过一个实例进行选择器讲解:


简单选择器

简单的选择器可以是通配符,也可以是类型、名称或类名的任意组合。基于上面的视觉树示例,以下列举了一些有效的简单选择器:
* #container1
* VisualElement
* VisualElement#container1
* VisualElement.yellow
* Button#OK.yellow:hover
Type
将 USS 附加到视觉元素:
可以将 Unity 样式表 (USS) 附加到任何视觉元素。样式规则适用于视觉元素及其所有后代。必要时,还会自动重新应用样式表。
应使用标准 Unity API(如 AssetDatabase.Load() 或 Resources.Load())来加载 StyleSheet 对象。使用 VisualElement.styleSheets.Add() 方法可将样式表附加到视觉元素。
如果在 EditorWindow 运行时修改 USS 文件,则会立即应用样式更改。
样式的应用过程对于使用 UIElements 的开发者是透明的。需要时(层级视图更改、样式表重新加载)会自动重新应用样式表。
TypeName { ...}使用 Type 选择器可根据 C# 类型来匹配元素。例如,Button 匹配两个按钮。
使用 Type 选择器时,仅指定具体的对象类型。不要在类型名称中包含命名空间。
Name
#name { ...}使用 Name 选择器可根据 VisualElement.name 属性的值来匹配元素。 例如,#Cancel 根据名称匹配第二个按钮。
元素名称在面板内应该是唯一的。此建议并非强制要求,但使用非唯一名称可能会导致意外匹配。
在为元素分配名称时不要包含 #。
Class
.class { ...}使用 Class 选择器可匹配分配给特定类的元素。
要匹配元素,该选择器不必指定分配给元素的所有类。指定单个类名将会匹配分配了同一个类的元素。例如,.yellow 会匹配名为 container2 的元素和名为 OK 的按钮元素。
如果在选择器中指定多个类,则对于要匹配的元素,必须为其分配相同的类名。
在为元素分配类名时不要包含 .。
类名不能以数字开头。
通配符
* { ...}匹配任何元素。
伪状态
:pseudo-state { ...}使用伪状态可匹配进入特定状态时的元素。例如,Button:hover 匹配 Button 类型的视觉元素,但仅当用户将光标放在视觉元素上时才符合条件。
支持的伪状态:
* hover:光标悬停在视觉元素上。
* active:可交互的视觉元素。
* inactive:不可交互的视觉元素。
* focus:当前聚焦的视觉元素。
* selected:未使用。
* disabled:enabled == false 的视觉元素。
* enabled:enabled == true 的视觉元素。
* checked:视觉元素是一个 Toggle 元素并已选中。
* root:树中的最高层级视觉元素。
在其他简单选择器之后指定伪状态。伪状态不能扩展。只支持一组预定义的伪状态。
复杂选择器

复杂选择器是简单选择器与分隔符的组合。复杂选择器还包括选择器列表,它们提供了一种将相同样式应用于许多元素的简化方式。
分隔符
空格:匹配元素的所有后代
> :匹配在分隔符 前的选择器匹配的元素 的直接后代。
例如 :
#container1 .yellow: 匹配内部元素和第一个按钮
#container2 > .yellow: 只匹配内部元素
选择器列表
使用选择器列表将相同的样式定义应用于许多元素。每个选择器用逗号分隔,每个选择器可以是简单或复杂的选择器。
例如 :
#container1, Button { padding-top:10 }等同于
#container1 { padding-top: 10 } Button { padding-top: 10}选择器优先级
如果多个选择器匹配相同的元素,则具有最高特异性的选择器优先。对于简单选择器,基本特异性规则为:
Name > Class > Type > 通配符 *
如果两个选择器在同一样式表中相等,则文件中最后出现的选择器优先。
用户定义的样式表中的选择器优先于 Unity 提供的默认样式表。
解析优先级的第二种方式是考虑树的遍历顺序(为了应用样式)。样式表附加到的具有较高深度和同级索引的元素优先。
(注意,!important 关键字将被忽略)
最后,在 C# 中设置的值始终具有最高的特异性,并将覆盖 USS 中的任何样式。
USS属性类型

内置属性与自定义属性
使用 USS 时,可为内置的 VisualElement 属性或 UI 代码中的自定义属性指定值。
除了从 USS 文件中读取值之外,还可以使用 VisualElement 的 C# 属性在 C# 中分配内置属性值。在 C# 中分配的值将覆盖 Unity 样式表 (USS) 中的值。
可使用自定义属性 API 来扩展 USS。自定义 USS 属性需要 -- 前缀。
属性值
长度
UIElements 支持像素 (px) 和百分比 (%) 作为长度的度量单位。像素值是绝对值,而百分比通常相对于元素父级。
例如:
width:200px; 表示宽度为 200 像素。
width:50%; 表示宽度为父元素宽度的一半。
务必指定度量单位。如果未指定度量单位,则 UIElements 会假定属性值以像素为单位。
注意:0 是一个不需要度量单位的特殊值。
数值
数值表示为浮点或整数字面值。例如:flex:1.0。
关键字
某些内置属性支持特定关键字。关键字提供描述性名称而不是数字。例如:position:absolute。所有属性都支持 initial 全局关键字,该关键字将属性重置为默认值。
颜色
UIElements 支持以下字面颜色值和函数:
* 十六进制值:#FFFF00(rgba,每个通道一个字节)、#0F0 (rgb)
* RGB 函数:rgb(255, 255, 0)
* RGBA 函数:rgba(255, 255, 0, 1.0)
* 颜色关键字:blue、transparent
资源
可使用 resource() 或 url() 函数来引用资源。
例如,指定 background-image: resource("Images/img.png") 可将 Images 目录中的 img.png 指定为背景图像。导入期间将解析引用的资源。
resource() 函数接受位于 Resources 文件夹或 Editor Default Resources 文件夹下的文件,但注意以下几点:
* 如果文件位于 Resources 文件夹下,不要包含文件扩展名。例如:background-image: resource("Images/my-image")。
* 如果文件位于 Editor Default Resources 下,必须包含文件扩展名。例如:background-image: resource("Images/default-image.png")。
此外,在加载纹理时,resource() 提供了一种处理高 DPI/Retina 屏幕的便捷方法。如果在同一位置存在具有相同文件名和后缀 @2x 的纹理,Unity 将根据屏幕 DPI 自动加载该纹理。 例如,如果在 USS 中使用 resource("myimage"),Unity 将加载 Resources/myimage.png 或 Resources/myimage@2x.png。
url() 函数要求文件路径相对于项目根目录或包含 USS 文件的文件夹。必须包含文件扩展名。在以下示例中,USS 文件位于 Assets\Editor\USS 中,_thumb.png_ 背景图像位于 Assets\Editor\Resources 中:
* 根据 USS 文件的位置,使用以下示例表示相对路径:url("../Resources/thumb.png");
* 根据项目的位置,使用以下示例之一表示绝对路径:url("/Assets/Editor/Resources/thumb.png");、url("project:/Assets/Editor/Resources/thumb.png"); 或 url("project:///Assets/Editor/Resources/thumb.png"); 例如:background-image: url("Images/my-image.png")。
字符串
使用引号指定字符串值。例如:--my-property: "foo"。
将 USS 附加到视觉元素

可以将 Unity 样式表 (USS) 附加到任何视觉元素。样式规则适用于视觉元素及其所有后代。必要时,还会自动重新应用样式表。
应使用标准 Unity API(如 AssetDatabase.Load() 或 Resources.Load())来加载 StyleSheet 对象。使用 VisualElement.styleSheets.Add() 方法可将样式表附加到视觉元素。
如果在 EditorWindow 运行时修改 USS 文件,则会立即应用样式更改。
样式的应用过程对于使用 UIElements 的开发者是透明的。需要时(层级视图更改、样式表重新加载)会自动重新应用样式表。
USS支持的属性

官方连接:https://docs.unity3d.com/2019.4/Documentation/Manual/UIE-USS-SupportedProperties.html
包含布局、边界、背景等属性设置案例:
USS 样式表编写

建议 UIElements 采用BEM作为样式元素的方法。
关于BEM:
BEM 作为块元素修饰符。是一个简单的系统,有助于编写结构化、明确、易于维护的选择器。通过 BEM 可以向元素分配类(class),然后将这些类用作样式表中的选择器。
简单来说:就是通过一个规则,编写class,使选择器更易于阅读和维护。
官方连接:https://docs.unity3d.com/2019.4/Documentation/Manual/UIE-USS-WritingStyleSheets.html

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-22 01:19 , Processed in 0.154940 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表