1 前言

UI Toolkit简介 中介绍了样式属性,UI Toolkit容器UI Toolkit元素 中介绍了容器和元素,本文将介绍样式选择器(Selector),主要包含样式类选择器(Class Selector)、C# 类选择器(Type Selector)、名称选择器(Name Selector)、通用选择器(Universal Selector)、后代选择器(Descendant Selector)、子选择器(Child Selector)、多重选择器(Multiple Selector)、伪类选择器(Pseudo Class)等。样式选择器官方介绍见→USS selectors

2 简单选择器(Simple Selector)

​ 简单选择器优先级:

//       *         <    C# Type    <     .Name      <    #Name
// 通用选择器 < C#类选择器 < 样式类选择器 < 名称选择器
Universal Selector < Type Selector < Class Selector < Name Selector

2.1 样式类选择器(Class Selector)

​ Class 选择器是命名以 "." 号开头的选择器(如:.red、.abc、.xyz 等),需要手动绑定到元素上,官方介绍见→Class selectors

1)创建 UI

​ 在 UI Builder 的 Hierarchy 窗口中创建 UI 如下。

​ 显示如下。

2)创建 USS 文件

​ 在 StyleSheets 窗口点击 "+" 号,选择 Create New USS 选项,如下。选择 USS 文件保存路径,命名为 StyleSelectorDemo。

3)创建选择器

​ 在 StyleSheets 窗口的 selector 框中输入 ".textColor",如下。注意:textColor 前面有个点,命名可以随意,如:demo、test 等都行。

​ 按 Enter 键后,创建了 selector,如下。

4)修改选择器的属性

​ 选中 ".textColor" 选择器,在 Inspector 窗口修改文本颜色,如下。

5)绑定选择器到元素

​ 将 ".textColor" 选择器拖拽到 Hierarchy 或 Viewport 窗口中相关元素上,实现样式选择器与元素的绑定。

​ 也可以通过以下方式绑定元素:选中元素后,在 Inspector 窗口的 Style Class List 中添加 selector,如下。

​ 选择器绑定到元素后,在 Inspector 窗口可以看到元素绑定的选择器,如下。可以通过后面的 "x" 号删除选择器。

6)显示效果

​ Label 和 Button 都手动绑定了 ".textColor" 选择器,显示效果如下。

2.2 C# 类选择器(Type Selector)

​ Type 选择器是以元素的 C# 类名命名的选择器(如:Label、Button、VisualElement 等),会自动绑定到对应 Type 的元素上,不需要手动绑定,官方介绍见→Type selectors

1)创建选择器

​ 在 StyleSheets 窗口创建名为 "Label" 的选择器,如下。

2)修改选择器的属性

​ 选中 "Label" 选择器,在 Inspector 窗口修改文本样式为斜体,如下。

3)显示效果

​ Label 元素会自动绑定 "Label" 选择器,Button 元素则不会,即使手动将 "Label" 选择器拖拽到 Button 元素上,也不会绑定成功。显示效果如下。

2.3 名称选择器(Name Selector)

​ Name 选择器是命名以 "#" 号开头的选择器(如:#Name、#Abc、#Xyz 等),会自动绑定到对应 Name 的元素上,不需要手动绑定,官方介绍见→Name selectors

1)修改元素名

​ 新创建的元素默认元素名为空,修改元素名如下。

2)创建选择器

​ 在 StyleSheets 窗口创建名为 "Button1" 的选择器,如下。

3)修改选择器的属性

​ 选中 "Button1" 选择器,在 Inspector 窗口修改背景颜色,如下。

4)显示效果

​ Button1 元素会自动绑定 "Button1" 选择器,Label1 元素则不会,即使手动将 "Button1" 选择器拖拽到 Label1 元素上,也不会绑定成功。显示效果如下。

2.4 通用选择器(Universal Selector)

​ Universal 选择器是以 "*" 号命名的选择器,会自动绑定到所有元素上,不需要手动绑定,官方介绍见→Universal selectors

1)创建选择器

​ 在 StyleSheets 窗口创建名为 "*" 的选择器,如下。

2)修改选择器的属性

​ 选中 "*" 选择器,在 Inspector 窗口修改边框宽度和颜色,如下。

3)显示效果

​ 所有元素都会自动绑定 "*" 选择器,显示效果如下。

3 复杂选择器(Complex Selector)

​ 复杂选择器是指由多个简单选择器按照特定规则组合而成的选择器。

3.1 后代选择器(Descendant Selector)

​ Descendant 选择器由多个简单选择器通过空格连接而成,它匹配的是某个 UI 元素底下符合规则的所有层级的子元素,官方介绍见→Descendant selectors

// 在selector1匹配的子元素中匹配selector2, ...
// 选择器的顺序不同匹配的元素也不同
selector1 selector2 {...}

1)UI 搭建

​ UI 层级结构如下,其中 Background、VE1、VE2、VE3 都是 VisualElement,Label1、Label2、Label3 都是 Label。

​ 创建以下简单选择器。其中,Lable 选择器中修改了字体大小为 30;.red 选择器中修改了背景颜色为红色,并绑定到 VE1,.green 选择器中修改了背景颜色为绿色,并绑定到 VE2;.blue 选择器中修改了背景颜色为蓝色,并绑定到 VE3。

​ UI 显示如下。

2)创建 Descendant 选择器

​ 在 StyleSheets 窗口创建以下选择器。

  • "#VE1 Label" 选择器:修改字体为斜体;
  • ".green Label" 选择器:修改字体颜色为黑色;
  • "#Background *" 选择器:设置 3px 的黄色边框。

3)显示效果

​ 可以看到,"#VE1 Label" 选择器匹配的是 Label1 元素,".green Label" 选择器匹配的是 Label2 元素,"#Background *" 选择器匹配的是 VE1、VE2、VE3、Label1、Label2、Label3 元素。

3.2 子选择器(Child Selector)

​ Child 选择器由多个简单选择器通过 " > " 连接而成,它匹配的是某个 UI 元素底下符合规则的第一层级的子元素,官方介绍见→Child selectors

// 在selector1匹配的子元素中匹配selector2, ...
// 选择器的顺序不同匹配的元素也不同
selector1 > selector2 {...}

1)UI 搭建

​ 同 3.1 1)节。

2)创建 Child 选择器

​ 在 StyleSheets 窗口创建以下选择器。

  • "#VE1 > Label" 选择器:修改字体为斜体;
  • ".green > Label" 选择器:修改字体颜色为黑色;
  • "#Background > *" 选择器:设置 3px 的黄色边框。

3)显示效果

​ 可以看到,"#VE1 > Label" 选择器匹配的是 Label1 元素,".green > Label" 选择器匹配的是 Label2 元素,"#Background > *" 选择器匹配的是 VE1、VE2、VE3 元素。

3.3 多重选择器(Multiple Selector)

​ Multiple 选择器由多个简单选择器直接而成,它匹配的是符合所有规则的元素,官方介绍见→Multiple selectors

// 匹配同时满足selector1、selector2、...的元素
// 选择器的顺序不同匹配的元素相同
selector1selector2 {...}

​ 说明:Class 选择器可以通过 "." 区分,Name 选择器可以通过 "#" 区分,Type 选择器没有区分符号,因此,一个多重选择器中最多允许有一个 Type 选择器,并且必须放在第一位。

1)UI 搭建

​ 同 3.1 1)节。

2)创建 Multiple 选择器

​ 在 StyleSheets 窗口创建以下选择器。

  • "Label#Label1" 选择器:修改字体为斜体;
  • "VisualElement.green" 选择器:设置圆角半径 Radius 为 20 px;
  • "Label*" 选择器:设置 3px 的黄色边框。

3)显示效果

​ 可以看到,"Label#Label1" 选择器匹配的是 Label1 元素,"VisualElement.green" 选择器匹配的是 VE2 元素,"Label*" 选择器匹配的是 Label1、Label1、Label3 元素。

4 伪类选择器(Pseudo Class)

​ Pseudo 选择器是指由简单选择器和状态符连接而成,它匹配的是特定状态下的元素,官方介绍见→Pseudo-classes

// 匹配满足selector且进入state状态的元素
selector:state {...}

​ 状态符主要以下几种。

  • :hover:光标悬浮在元素上。
  • :active:用户与元素交互。
  • :inactive:用户停止与元素交互。
  • :focus:元素获得焦点。
  • :disabled:元素进入 disabled 状态。
  • :enabled:元素进入 enabled 状态。
  • :checked:Toggle 或 RadioButton 被选中。
  • :root:元素成为根元素。

1)UI 搭建

​ 同 3.1 1)节。

2)创建 Pseudo 选择器

​ 在 StyleSheets 窗口创建以下选择器。

  • "#Label1:hover" 选择器:修改字体为斜体;
  • ".green:hover" 选择器:设置圆角半径 Radius 为 20 px;
  • "*:hover" 选择器:设置 3px 的黄色边框。

3)显示效果

​ 可以看到,"#Label1:hover" 选择器匹配的是进入 hover 状态的 Label1 元素,".green:hover" 选择器匹配的是进入 hover 状态的 VE2 元素,"*:hover" 选择器匹配的是进入 hover 状态的 VE1、VE2、VE3、Label1、Label1、Label3 元素。

5 样式切换

1)样式选择器的添加和删除

// 如果visualElement有StyleName样式, 就将其删除; 如果visualElement没有StyleName样式, 就将其添加
visualElement.ToggleInClassList("StyleName"); // StyleName是样式选择器名, 不需要前面的"."

​ 说明:只能添加和删除样式类选择器(以 "." 命名开头的选择器),其他选择器都是自动绑定到元素上的。

2)uss 样式文件替换

VisualElement root = GetComponent<UIDocument>().rootVisualElement; // 根容器
VisualElementStyleSheetSet styleSheetSet = root.styleSheets; // 样式集合
styleSheetSet.Remove(oldStyleSheet); // 移除旧样式, oldStyleSheet是StyleSheet类型变量, 指向一个uss文件
styleSheetSet.Add(newlightTheme); // 添加新样式, newStyleSheet是StyleSheet类型变量, 指向一个uss文件

6 样式应用

​ 本节将实现亮主题和暗主题的切换,完整资源见→Unity3D切换样式主题

​ Page.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">
<Style src="project://database/Assets/SwitchTheme/StyleSheets/LightTheme.uss?fileID=7433441132597879392&amp;guid=b86be23b06b471b43a7ea453aed7df74&amp;type=3#LightTheme" />
<ui:VisualElement name="Background" class="bgColor" style="flex-direction: row; flex-grow: 1; background-image: url(&apos;project://database/Assets/SwitchTheme/Textures/Background_Sky.png?fileID=2800000&amp;guid=49e1c76bfa6ef0546a39fd2bceb69b9a&amp;type=3#Background_Sky&apos;);">
<ui:VisualElement name="Left" style="flex-grow: 0; border-right-width: 2px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); flex-basis: 30%;">
<ui:VisualElement name="Top" class="dark top" style="flex-basis: 30%; margin-bottom: 0; border-bottom-width: 2px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0);" />
<ui:VisualElement name="Middle" style="flex-basis: auto; flex-grow: 1;">
<ui:Label text="Label" display-tooltip-when-elided="true" class="item middleBg middle" style="flex-grow: 1; -unity-text-align: middle-center; font-size: 60px; flex-shrink: 1; margin-top: 5px; margin-bottom: 5px;" />
<ui:Label text="Theme" display-tooltip-when-elided="true" name="Theme" class="item middle" style="flex-grow: 1; -unity-text-align: middle-center; font-size: 60px; flex-shrink: 1; margin-top: 5px; margin-bottom: 5px;" />
<ui:RadioButtonGroup value="-1" choices="Light,Drak" name="SwitchTheme" class="middle hide" style="flex-grow: 0; font-size: 45px; -unity-text-align: middle-center; align-items: center; justify-content: center; flex-direction: column; margin-left: 0; margin-right: 0; margin-top: 5px; margin-bottom: 5px; flex-shrink: 1;" />
<ui:Label text="Label" display-tooltip-when-elided="true" class="item middle" style="flex-grow: 1; -unity-text-align: middle-center; font-size: 60px; flex-shrink: 1; margin-top: 5px; margin-bottom: 5px;" />
</ui:VisualElement>
<ui:VisualElement name="Bottom" style="flex-basis: 25%; border-top-width: 2px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0);">
<ui:Label text="Bottom" display-tooltip-when-elided="true" style="flex-shrink: 1; flex-grow: 1; font-size: 100px; -unity-text-align: middle-center;" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="Right" style="flex-grow: 0; flex-basis: 70%; align-items: center; justify-content: center;">
<ui:Label text="Work Space" display-tooltip-when-elided="true" class="right" />
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>

​ LightTheme.uss

Label {
color: rgb(48, 47, 47);
} RadioButton:hover {
background-color: rgb(217, 217, 217);
} .unity-radio-button__checkmark-background {
margin-right: 10px;
width: 30px;
height: 30px;
justify-content: center;
align-items: center;
border-left-width: 1px;
border-right-width: 1px;
border-top-width: 1px;
border-bottom-width: 1px;
border-top-left-radius: 20px;
border-bottom-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
background-color: rgb(43, 43, 43);
border-left-color: rgba(248, 242, 242, 255);
border-right-color: rgba(248, 242, 242, 255);
border-top-color: rgba(248, 242, 242, 255);
border-bottom-color: rgba(248, 242, 242, 255);
padding-top: 0;
} .unity-radio-button__checkmark {
width: 15px;
height: 15px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
justify-content: center;
align-items: center;
background-color: rgb(217, 213, 213);
} .bgColor {
-unity-background-image-tint-color: rgb(255, 255, 255);
} .top {
background-image: url('project://database/Assets/SwitchTheme/Textures/unity_dark.png?fileID=2800000&guid=49ee81a1e2e15df46968d5d1978abc12&type=3#unity_dark');
-unity-background-scale-mode: scale-to-fit;
} .middle {
background-color: rgba(0, 239, 255, 0.39);
} .right {
-unity-text-align: middle-center;
-unity-font-style: bold;
font-size: 200px;
color: rgb(0, 168, 255);
justify-content: center;
align-items: center;
-unity-text-outline-width: 1px;
-unity-text-outline-color: rgb(255, 31, 0);
text-shadow: 5px 2px 1px rgb(255, 255, 255);
} .hide {
display: none;
} .item:hover {
background-color: rgb(58, 56, 56);
color: rgb(219, 216, 216);
} .middle {
background-color: rgba(0, 239, 255, 0.39);
}

​ DarkTheme.uss

Label {
color: rgb(212, 212, 212);
} RadioButton:hover {
background-color: rgb(38, 38, 38);
} .unity-radio-button__checkmark-background {
margin-right: 10px;
width: 30px;
height: 30px;
justify-content: center;
align-items: center;
border-left-width: 1px;
border-right-width: 1px;
border-top-width: 1px;
border-bottom-width: 1px;
border-top-left-radius: 20px;
border-bottom-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
background-color: rgb(255, 255, 255);
padding-top: 0;
} .unity-radio-button__checkmark {
width: 15px;
height: 15px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
justify-content: center;
align-items: center;
background-color: rgb(51, 50, 50);
} .bgColor {
-unity-background-image-tint-color: rgb(132, 132, 132);
} .top {
background-image: url('project://database/Assets/SwitchTheme/Textures/unity_light.png?fileID=2800000&guid=92a215376eed0c9498000506d15b4afe&type=3#unity_light');
-unity-background-scale-mode: scale-to-fit;
} .middle {
background-color: rgba(46, 44, 44, 0.39);
} .right {
-unity-text-align: middle-center;
-unity-font-style: bold;
font-size: 200px;
color: rgb(197, 194, 194);
justify-content: center;
align-items: center;
-unity-text-outline-width: 1px;
-unity-text-outline-color: rgb(255, 216, 0);
text-shadow: 5px 2px 1px rgb(53, 52, 52);
} .hide {
display: none;
} .item:hover {
background-color: rgb(214, 211, 211);
color: rgb(46, 45, 45);
}

​ SwitchTheme.cs

using UnityEngine;
using UnityEngine.UIElements; public class SwitchTheme : MonoBehaviour {
private VisualElement root; // 根容器
private RadioButtonGroup switchThemeElement; // 切换主题元素
private VisualElementStyleSheetSet styleSheetSet; // 主题集合
[SerializeField] private StyleSheet lightTheme; // 亮主题, 指向LightTheme.uss文件
[SerializeField] private StyleSheet darkTheme; // 暗主题, 指向DarkTheme.uss文件 private void Awake() {
root = GetComponent<UIDocument>().rootVisualElement;
styleSheetSet = root.styleSheets;
Label themeLabel = root.Q<Label>("Theme");
themeLabel.RegisterCallback<ClickEvent>(OnClick);
switchThemeElement = root.Q<RadioButtonGroup>("SwitchTheme");
switchThemeElement.RegisterValueChangedCallback(OnValueChanged);
} private void OnClick(ClickEvent e) { // 点击回调函数
switchThemeElement.ToggleInClassList("hide");
} private void OnValueChanged(ChangeEvent<int> e) { // value变化回调函数
if (e.newValue == 0) { // 切换为亮主题
styleSheetSet.Remove(darkTheme);
styleSheetSet.Add(lightTheme);
} else { // 切换为暗主题
styleSheetSet.Remove(lightTheme);
styleSheetSet.Add(darkTheme);
}
}
}

​ 运行效果如下。

​ 声明:本文转自【Unity3D】UI Toolkit样式选择器

【Unity3D】UI Toolkit样式选择器的更多相关文章

  1. CSS链接四种状态注意顺序、UI伪类选择器的顺序

    css定义超链接是要有先后顺序的.否则,可能会出现某个或某几个样式不起作用的bug.例如:visited与hover顺序颠倒了,则不能显示hover和active的样式了. 正确的顺序: a:link ...

  2. UWP学习记录3-设计和UI之样式

    UWP学习记录3-设计和UI之样式 1.颜色 在系统的“设置”>“个性化”>“颜色”里,提供了主题色选择.选定主题色后,会根据颜色亮度的 HSB 值创建浅色和深色的主题色. 应用可使用阴影 ...

  3. JS实战 · 仿css样式选择器

    代码如下: <html> <head>     <meta http-equiv="Content-Type" content="text/ ...

  4. CSS样式选择器优先级

    CSS样式选择器分为4个等级,a.b.c.d,可以以这四种等级为依据确定CSS选择器的优先级. 1.如果样式是行内样式(通过Style=””定义),那么a=12.b为ID选择器的总数3.c为Class ...

  5. BCG界面库下的Windows8 UI界面样式www.webui8.com

    BCG界面库下的Windows8 UI界面样式(Metro风格)控件主要有以下一些功能: 规则的大块磁贴 支持完整键盘导航 Tile组 标题(Caption) 标题按钮(Caption buttons ...

  6. CSS样式选择器

    <!-- css样式选择器 HTML选择器 类选择器 ID选择器 关联选择器 组合选择器 伪元素选择器 selector{ /* selector是样式选择器 property:value; / ...

  7. 关于样式选择器:hover出现忽闪现象

    有时候在做项目的时候会想给一个元素添加一个遮罩效果,然后鼠标划过去的时候,遮罩消失,一般最简单的方法就是使用样式选择器:hover,但是经历过才知道恶心,有种灯泡快要坏的感觉,闪瞎自己的眼睛,于是诞生 ...

  8. jquery选择器扩展之样式选择器

    https://github.com/wendux/style-selector-jQuery-plugin http://blog.csdn.net/duwen90/article/details/ ...

  9. angular动态绑定样式以及改变UI框架样式的方法

    一:angular动态绑定样式 举个栗子: <tr *ngFor="let dataTr of tableData;let i = index" [formGroupName ...

  10. 前端基础:CSS样式选择器

    前端基础:CSS样式选择器 CSS概述 CSS是Cascading Style Sheets的简称,中文意思是:层叠样式表,对html标签的渲染和布局.CSS规则由两个主要的部分组成:1.选择器:2. ...

随机推荐

  1. 「学习笔记」CDQ分治

    CDQ 分治的思想最早由 IOI2008 金牌得主陈丹琦在高中时整理并总结,目前这个思想的拓展十分广泛. 优点:可以将数据结构或者 DP 优化掉一维 缺点:这是离线算法. 引入 让我们来看一个问题 有 ...

  2. win10系统网络图标变成一个地球模型并且无法连上网络

    最近在家远程办公,但是遇到个很棘手的问题,电脑突然连不上无线网络了.... 无线网络图标变成地球模型如下:

  3. 利用java来实现计算器的加减乘除

    package bag; import java.util.Scanner; public class Demo06 { public static void main(String[] args) ...

  4. 【转载】Linux虚拟化KVM-Qemu分析(二)之ARMv8虚拟化

    原文链接: 作者:LoyenWang 出处:https://www.cnblogs.com/LoyenWang/ 公众号:LoyenWang 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作 ...

  5. 如何使用CCXT交易数字货币现货

    更多精彩内容,欢迎关注公众号:数量技术宅,也可添加技术宅个人微信号:sljsz01,与我交流. 数字货币现货标准化接口 数字货币市场与股票.期货市场最大的不同点在于数字货币主流交易所数量很多.举个例子 ...

  6. C# DateTime 时间格式化

    今天做任务的时候,数据库日期拼写需要 从凌晨到晚上最后一秒,但是传过来的日期数据是 当前的时间,下面是我尝试的解决方案. endTime.ToString("yyyy-MM-dd 23:59 ...

  7. pandas 删除重复项

    使用如下函数: drop_duplicates 具体示例如下: import pandas as pd # 建立一个dataframe数据 df = pd.DataFrame({'k1':['one' ...

  8. [kubernetes]二进制部署k8s集群

    0. 前言 采用二进制部署三主三工作节点的k8s集群,工作节点和Master节点共用服务器,因此只用到了三台服务器.master采用haproxy + keepalive实现高可用.实际生产环境中,建 ...

  9. Python图片与Base64相互转换

    import base64 #必须的 pic=open("img.png","rb")#读取本地文件 pic_base=base64.b64encode(pic ...

  10. ios添加库文件