Unity 新技术UIkit

简单介绍

UIBulider的使用

UIElement是一种类似于Html形式进行界面开发的方式,创建的EditorWidow包括以下3个文件。

image-20220317003751243

  • C#-代码控制界面逻辑 类似于js
  • Uss-样式控制器 类似于Css
  • Uxml-基础骨架模板 类型Html

image-20220317004247734

UIBulider界面

双击Asset打开编辑窗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class DialogGraphEditWindow : EditorWindow
{

private static VisualElement rootMain;

[OnOpenAsset(1)]
public static bool OpenAsset(int id,int line)
{
if (EditorUtility.InstanceIDToObject(id) is DialogTreeGraphAsset graph)
{
var window = GetWindow<DialogGraphEditWindow>();
window.titleContent = new GUIContent("对话窗");
var root = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/GraphWindow.uxml");

if (rootMain==null)
{
rootMain = root.Instantiate();
}
window.rootVisualElement.Add(rootMain);
window.minSize = new Vector2(600, 450);

return true;
}
return false;
}


}

Uss 样式表

形如这样的称为样式表uss,uss决定了ui元素的显示效果。

1
2
3
4
5
Label {
font-size: 20px;
-unity-font-style: bold;
color: rgb(68, 138, 255);
}

Uxml 模板

uxml模板类似于html,其中包含了所有的静态元素内容。

uxml使用uss决定其中ui元素的具体显示效果。

双击打开uxml时默认会自动打开可视化工具——UIBulider,在UiBulider中进行可视化的数据操作。

Ui 绑定

Ui绑定文件类似于JavaScript代码

我们可以在代码中使用相关的Api对Ui元素和样式表进行操作,如下所示:

动态操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class BagMgrWindow : EditorWindow
{
[MenuItem("Window/UI Toolkit/BagMgrWindow")]
public static void ShowExample()
{
BagMgrWindow wnd = GetWindow<BagMgrWindow>();
wnd.titleContent = new GUIContent("BagMgrWindow");
}

public void CreateGUI()
{
// Each editor window contains a root VisualElement object
VisualElement root = rootVisualElement;

// VisualElements objects can contain other VisualElement following a tree hierarchy.
VisualElement label = new Label("Hello World! From C#");
root.Add(label);

// Import UXML
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/EditorWindows/BagMgrWindow.uxml");
VisualElement labelFromUXML = visualTree.Instantiate();
root.Add(labelFromUXML);

// A stylesheet can be added to a VisualElement.
// The style will be applied to the VisualElement and all of its children.
var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/EditorWindows/BagMgrWindow.uss");
VisualElement labelWithStyle = new Label("Hello World! With Style");
labelWithStyle.styleSheets.Add(styleSheet);
root.Add(labelWithStyle);
}
}

Debug 工具

提供有Ui检查工具,其中可以查看Ui元素的显示状态和包围盒结构,树形结构等,类似html的浏览器F12.

image-20221121150027349

流程模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using UnityEditor;
using UnityEngine.UIElements;

public class IndexEditorWindow : EditorWindow
{
private static VisualElement rootMain;

[MenuItem("Fasty/主界面")]
public static void Open()
{
var root = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Index.uxml");

rootMain = root.Instantiate();

var window = GetWindow<IndexEditorWindow>();

window.rootVisualElement.Add(rootMain);

CreateUi();
InitEvent();

window.Show();
}

/// <summary>
/// 动态创建Ui
/// </summary>
private static void CreateUi()
{

}

/// <summary>
/// 处理事件
/// </summary>
private static void InitEvent()
{
var btn = rootMain.Q<Button>("showBtn");
btn.clicked += () => { rootMain.Q<Label>("title").text = "查看被点击了"; };

btn = rootMain.Q<Button>("descBtn");
btn.clicked += () => { rootMain.Q<Label>("title").text = "说明被点击了"; };
}
}

装备管理小案例

++2022年11月21日10:32:00更新++

此案例为Uitoolkit练习,使用Unity2021.3.11f1c2

初步设计

image-20221121105406061

简单装备管理设计

其中涉及到ListView控件参考:[Unity - Manual: Create list and tree views (unity3d.com)](https://docs.unity3d.com/2022.1/Documentation/Manual/UIE-ListView-TreeView.html#:~:text=Create a list view 1 Right-click in the,the ListView control in the Hierarchy window. 更多项目)

++ 🔖值得注意的是: 当因为修改脚本导致窗口无法打开时,可能是因为查找不到窗口的实例,在修正错误后,重启Unity编辑器才能正常打开窗体。++

ListView的使用

这里点击使用的是通用注册事件,同时也可以使用ListView的OnValueChange方法监听,在监听时获取不到text属性,可以在生成时将数据绑定到viewDataKey

1
2
3
4
5
6
7
8
9
10
11
12
13
var list = _rootMain.Q<ListView>();
var data = new ArrayList() { "A", "B", "C" };
list.itemsSource = data;
list.makeItem = () => new Label();
list.bindItem = (element, index) =>
{
((Label)element).text = data[index].ToString();
element.viewDataKey = data[index].ToString();
element.RegisterCallback<MouseDownEvent>((c) =>
{
Debug.Log($"点击了选项:{element.viewDataKey}");
}, TrickleDown.TrickleDown);
};