UIElement(现更名为UI ToolKit但是程序集名称还是UIElement)是Unity新推出的一种UI解决方案,目标是一站式解决Editor+Runtime的UI设计需求,使用C# + HTML的形式进行开发,其中HTML用以定义UI样式和内容,C#引用HTML定义内容+绑定数据,并且与GamePlay进行交互。
我们来看看他的底层是怎么样的:
上面提到UIElement使用RMGUI的模式,并且基于其做了按需更新的模式达到性能优化的效果,但目前Unity编辑器拓展主流仍然是Immediate Mode GUI (IMGUI)的形式,他不保存任何状态写起来非常爽快,但是问题就是需要每帧无差别的收集所有VB/IB然后进行绘制操作,相比RMGUI按需更新的模式就比较消耗性能。
首先在Assets下创建一个名为Editor的文件夹,和编辑器有关的监本都要创建在这个文件夹下。然后在Editor文件夹下右键——Create——UIElement Editor Window,然后就会出现C#,UXML,USS三个文件。
C#
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class TestEditorWindow : EditorWindow
{
[MenuItem("Window/UIElements/TestEditorWindow")]
public static void ShowExample()
{
TestEditorWindow wnd = GetWindow();
wnd.titleContent = new GUIContent("TestEditorWindow");
}
public void OnEnable()
{
//创建根节点
VisualElement root = rootVisualElement;
//读取UXML
var visualTree = AssetDatabase.LoadAssetAtPath("Assets/Editor/TestEditorWindow.uxml");
//读取USS
var styleSheet = AssetDatabase.LoadAssetAtPath("Assets/Editor/TestEditorWindow.uss");
//创建新的子节点
VisualElement labelFromUXML = visualTree.CloneTree();
//为UXML添加USS样式
labelFromUXML.styleSheets.Add(styleSheet);
//将子节点添加到根节点
root.Add(labelFromUXML);
}
}
UXML
主要关注Label text这一行,指定了当前标签的文本内容。
CSS
Label {
font-size: 20px;
-unity-font-style: bold;
color: rgb(68, 138, 255);
}
css则指定了当前标签的具体样式。
在上一章中我们就创建了VisualElement类型根节点,之后将子节点挂在该根节点上
1.均在UnityEngine.UIElements命名空间下
2.无符号表示允许子元素数量是任意数量的VisualElement
3.X字符表示不允许有子元素
4.不作特殊说明,均包含所有VisualElement属性
根据其内容绘制一个框
显示文本的元素
文本标签
显示图像
绘制IMGUI内容的元素
用法示例:
viewElement.Q().onGUIHandler += OnDrawCustomGUI;
private void OnDrawCustomGUI()
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("TestIMGUI");
if (GUILayout.Button("Button"))
{
Debug.LogError("TestIMGUI");
}
EditorGUILayout.EndHorizontal();
}
通过一个toggle控制展开或收起
USS
.h
{
height: 150px;
background-image: resource("Assets/Editor/Sample1/unity.png");
}
.pic
{
width :50px;
height:50px;
background-image: resource("Assets/Editor/Sample1/unity.png");
}
resource里面指定的是当前需要显示图片所在的位置
UXML
C#侧的代码与之前一样,加载出对应的UXML和USS并应用。
结果
1.Template (X)
通过对另一个UXML模板的引用,使用其Instance元素来实例化
2.Instance (X)
一个模板的实例
3.TemplateContainer (X)
模板容器
模板UXML定义为portrait.uxml
在另一个UXML使用时
C#侧的代码去掉了之前加载USS部分的代码。
结果
此功能可以用在一些较为常用的通用功能绘制等部分,避免大量冗余代码,后续的使用只需要实例化模板部分即可。
所有字段的抽象基类
标准按钮
按下时反复执行操作的按钮
开关(复选框)
滚动条
滑动条
Int类型的滑动条
允许用户指定最小值和最大值的滑块
一个只能获取底层字符串值的字段Enum
多选菜单
图层单选菜单
图层多选菜单
标签单选菜单
进度条
USS
.btn
{
width :100px;
height:30px;
}
.scr
{
height:200px;
}
.sliH
{
width:100px;
}
.sliV
{
height:100px;
}
.efi
{
width:100px;
height:15px;
}
UXML
结果
1.TextInputBaseField< TValueType > (X)
所有文本字段的抽象基类
2.TextField(X)
可编辑的文本
-继承自TextInputBaseField< string >
3.IntegerField(X)
整数(32位)值的文本
4.LongField (X)
长整数(64位)值的文本
5.FloatField(X)
单精度浮点值的文本
6.DoubleField(X)
双精度浮点值的文本
7.Vector2Field(X)
两个文本框,接受按 float 进行编辑的Vector2类型文本
8.Vector2IntField(X)
两个文本框,接受按 int 进行编辑的Vector2类型文本
9.Vector3Field(X)
三个文本框,接受按 float 进行编辑的Vector3类型文本
10.Vector3IntField(X)
三个文本框,接受按 Int 进行编辑的Vector3类型文本
11.Vector4Field(X)
四个文本框,接受按 float 进行编辑的Vector4类型文本
12.RectField(X)
四个文本框,接受按 float 进行编辑的Rect类型文本
13.RectIIntField(X)
四个文本框,接受按 Int 进行编辑的Rect类型文本
14.BoundsField(X)
六个文本框,接受按 float 进行编辑的Bounds类型文本
15.BoundsIntField(X)
六个文本框,接受按 Int 进行编辑的Bounds类型文本
.fraSmall
{
width:150px;
height:20px;
}
.fraBig
{
width:300px;
height:50px;
}
用于编辑值的标签和字段
用于编辑字符串类型值的标签和字段
.container {
background-color: rgb(80, 80, 80);
flex-direction: column;
}
Label {
background-color: rgb(80, 80, 80);
}
TextField:hover {
background-color: rgb(255, 255, 0);
}
FloatField {
background-color: rgb(0, 0, 255);
}
C#及对应Editor下的脚本:
[ExecuteInEditMode]
public class TankScript : MonoBehaviour
{
public string tankName = "Tank";
public float tankSize = 1;
private void Update()
{
gameObject.name = tankName;
gameObject.transform.localScale = new Vector3(tankSize, tankSize, tankSize);
}
}
[CustomEditor(typeof(TankScript))]
public class TankEditor : Editor
{
public override VisualElement CreateInspectorGUI()
{
var visualTree = Resources.Load("tank_inspector_uxml") as VisualTreeAsset;
var uxmlVE = visualTree.CloneTree();
uxmlVE.styleSheets.Add(AssetDatabase.LoadAssetAtPath("Assets/Resources/tank_inspector_styles.uss"));
return uxmlVE;
}
}
颜色选择器
曲线编辑器
渐变编辑器
对象选择器
在Inspector中显示属性的元素
Toolbar
用于保存工具栏的容器
ToolbarButton(X)
工具栏按钮
ToolbarToggle(X)
工具栏开关
ToolbarMenu(X)
工具栏的下拉菜单
ToolbarSearchField(X)
工具栏的搜索字段
ToolbarPopupSearchField(X)
带有搜索选项弹出菜单的搜索字段
ToolbarSpacer(X)
在工具栏按钮之间插入固定数量的空白的元素
显示元素列表
可滚动视图,带有水平和垂直滚动条
用于在树层次结构中显示元素的视图
UIElements窗口,显示在其他内容之上
.fra
{
width:200px;
height:100px;
}
.fras
{
width:160px;
height:80px;
}
大家可以通过Unity Hub下载最新Unity2019.2.0b版本,然后通过Windows > UI > UIElements Samples打开。
在这里可以看到常用组件用法的Sample。