【Unity3D】UI Toolkit自定义元素

发布时间 2023-10-20 23:21:12作者: little_fat_sheep

1 前言

​ UI Toolkit 支持通过继承 VisualElement 实现自定义元素,便于通过脚本控制元素。另外,UI Toolkit 也支持将一个容器及其所有子元素作为一个模板,便于通过脚本复制模板。

​ 如果读者对 UI Toolkit 不是太了解,可以参考以下内容。

2 自定义元素

1)UI 搭建

​ 搭建 UI 如下,其中 Background 和 MyContainer 是 VisualElement,NameLab 是 Label,ActionBtn 是 Button。

img

​ TestCustom.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">
    <ui:VisualElement name="Background" style="flex-grow: 1; background-color: rgb(168, 156, 156);">
        <ui:VisualElement name="MyContainer" style="width: 300px; height: 250px; background-color: rgb(177, 185, 121); align-items: center; justify-content: center; margin-left: 20px; margin-right: 20px; margin-top: 20px; margin-bottom: 20px;">
            <ui:Label text="Name" display-tooltip-when-elided="true" name="NameLab" style="font-size: 50px; -unity-text-align: middle-center; margin-top: 10px; margin-bottom: 10px; margin-left: 10px; margin-right: 10px; padding-left: 0; padding-right: 0; padding-top: 0; padding-bottom: 0;" />
            <ui:Button text="Button" display-tooltip-when-elided="true" name="ActionBtn" style="font-size: 50px; margin-left: 10px; margin-right: 10px; margin-top: 10px; margin-bottom: 10px; background-color: rgb(217, 126, 40); justify-content: center; align-items: center;" />
        </ui:VisualElement>
    </ui:VisualElement>
</ui:UXML>

​ 显示如下。

img

2)创建模板

​ 选中 MyContainer,右键弹出菜单,选择 Create Template,选择 Resources 目录下保存 MyContainer.uxml 文件。

img

​ 保存模板后,Hierarchy 层级结构如下。可以看到,原来的 MyContainer 变成不可编辑的了,并且其上又套了一个空对象。这里先删去新的 MyContainer,只留下 Background,后面会通过脚本加载 MyContainer。

img

3)自定义元素

​ MyContainer.cs

using UnityEngine;
using UnityEngine.UIElements;

public class MyContainer : VisualElement {
    private TemplateContainer container;
    // 便于在UI Builder中导入自定义UI, 需要有无参构造函数
    public new class UxmlFactory : UxmlFactory<MyContainer> {}

    public MyContainer() {
        container = Resources.Load<VisualTreeAsset>("MyContainer").Instantiate();
        container.style.flexGrow = 1.0f;
        hierarchy.Add(container);
    }

    public MyContainer(int index) : this() {
        Label label = container.Q<Label>();
        label.text = "Name" + index;
        Button button = container.Q<Button>();
        button.clicked += () => Debug.Log("index=" + index);
    }
}

​ 编译后,在 UI Builder 中可以看到自定义的 UI,可以像内置 UI 一样拖拽到 Hierarchy 中使用。将鼠标悬浮在 MyContainer.cs 上,会弹出 UI 预览效果,如下。

img

4)加载元素

​ UILoader.cs

using UnityEngine;
using UnityEngine.UIElements;

public class UILoader : MonoBehaviour {
    private VisualElement root;

    private void Awake() {
        root = GetComponent<UIDocument>().rootVisualElement;
        var bodyContainer = root.Q("Background");
        bodyContainer.Clear();
        for(int i = 0; i < 3; i++) {
            MyContainer customContainer = new MyContainer(i);
            bodyContainer.Add(customContainer);
        }
    }
}

5)运行效果

img

​ 依次点击 3 个按钮,打印日志如下。

img

​ 声明:本文转自【Unity3D】UI Toolkit自定义元素