UIToolkit示例

参考 https://docs.unity3d.com/Manual/UIE-uxml-examples.html

实现纯图片按钮

    .image-button {
        background-color: rgba(0, 0, 0, 0);
        -unity-background-image-tint-color: rgb(200, 200, 200);
        border-left-width: 0;
        border-right-width: 0;
        border-top-width: 0;
        border-bottom-width: 0;
    }

    .image-button:hover:enabled {
        -unity-background-image-tint-color: rgb(255, 255, 255);
    }

    .image-button:hover:active:enabled {
        -unity-background-image-tint-color:  #888888;
    }

列表设置元素间距

  • 设置 ListView 的 fixItemHeight=50
  • 创建列表元素时,列表元素会自动设置高为50,添加一个子元素,设置height=40,则剩下的10做为间距
  • 接下来就是把鼠标悬停、选中效果从列表元素转移到子元素上
    • 创建列表元素时,给子元素添加 item-back 样式,或直接在UIBuilder中添加
    • 在界面中引用如下样式文件,就2个作用,清除原本的列表元素样式,设置子元素样式
          .unity-list-view__item {
              background-color: rgba(0, 0, 0, 0);
          }
      
          .unity-list-view__item:hover {
              background-color: rgba(0, 0, 0, 0);
          }
      
          .unity-list-view__item:checked {
              background-color: rgba(0, 0, 0, 0);
          }
      
          .unity-list-view__item:checked .item-back {
              border-left-color: rgba(12, 122, 237, 255);
              border-right-color: rgba(12, 122, 237, 255);
              border-top-color: rgba(12, 122, 237, 255);
              border-bottom-color: rgba(12, 122, 237, 255);
          }
      
          .unity-list-view__item:hover .item-back {
              border-left-color: rgba(85, 162, 242, 255);
              border-right-color: rgba(85, 162, 242, 255);
              border-top-color: rgba(85, 162, 242, 255);
              border-bottom-color: rgba(85, 162, 242, 255);
          }
      

Editor模式下自定义Tooltip

主要有2个难点

  1. 让窗口适配文本大小
    获取文本大小有2种方案
    1. 监听Label的 GeometryChangedEvent 事件,通过 resolvedStyle 获取大小
      Rect(element.resolvedStyle.left, element.resolvedStyle.top, element.resolvedStyle.width, element.resolvedStyle.height)
    2. 使用 TextElement.MeasureTextSize 直接计算文本占用的大小
  2. 让窗口自动显示在控件的上下左右合适的地方
    当前也有2种方案
    1. 使用unity提供的自动对齐
      有2个api可以实现,EditorWindow.ShowAsDropDown 和 PopupWindow.Show
      这2个api都可以显示弹窗,区别就在于 PopupWindow 可以在窗口显示后更改窗口大小,而 EditorWindow.ShowAsDropDown 则不行
      而上面获取文本大小又需要窗口显示后才能获取,因此最终方案是使用 PopupWindow.Show
      PopupWindow 会在 OnGUI 函数中调用 FitWindowToContent 实现实时更新窗口大小,最终是调用 ContainerWindow.GetDropDownRect ,这是内部函数
    2. 自己计算位置
      自己计算位置的最大问题是没找到获取所有屏幕的屏幕范围的方法
      操作系统是把所有显示器的显示范围都统一到一个虚拟坐标系中,只要能获取所有屏幕的显示范围,就可以计算出提示应该摆在哪里
      unity中只提供了 Display.displays 获取显示器大小,但缺少获取偏移的api
      最终实现是使用 1.1 + 2.1 来解决,也就是 PopupWindow.Show + 监听 GeometryChangedEvent
    public class CustomTooltip : PopupWindowContent
{
    private static CustomTooltip instance;
    private string tip;
    private Vector2 tipSize = new Vector2(100, 100);     //  给一个初始值
    private Label tooltipLabel;
    
    //  targetBounds 是需要提示的控件的边框
    public static void ShowTooltip(string text, Rect targetBounds)
    {
        HideTooltip();
        instance = new CustomTooltip(text);
        UnityEditor.PopupWindow.Show(targetBounds, instance);
    }

    public static void HideTooltip()
    {
        if (instance != null && instance.editorWindow != null)
        {
            try
            {
                instance.editorWindow.Close();
            } catch (Exception e) { }
        }
        instance = null;
    }

    public CustomTooltip(string tip)
    {
        this.tip = tip;
    }

    public override Vector2 GetWindowSize()
    {
        return tipSize;
    }

    public override void OnOpen()
    {
        InitializeUI();
        tooltipLabel.text = tip;
        tooltipLabel.RegisterCallback<GeometryChangedEvent>(OnFirstInit);
    }

    private void InitializeUI()
    {
        var root = editorWindow.rootVisualElement;

        //  root 的 flexDirection = FlexDirection.Column
        //  必须再添加一个 flexDirection = FlexDirection.Row 的元素,不然lable大小计算有问题
        VisualElement tooltipContainer = new VisualElement();
        tooltipContainer.style.flexDirection = FlexDirection.Row;
        root.Add(tooltipContainer);

        tooltipLabel = new Label();
        tooltipLabel.style.color = new Color(0.733f,0.733f,0.733f,1);
        tooltipLabel.style.backgroundColor = new Color(0.18f,0.18f,0.196f,1);
        tooltipLabel.style.fontSize = 12;
        tooltipLabel.style.position = Position.Absolute;
        tooltipLabel.style.paddingLeft = tooltipLabel.style.paddingRight = 8;
        tooltipLabel.style.paddingTop = tooltipLabel.style.paddingBottom = 5;
        tooltipContainer.Add(tooltipLabel);
    }

    //  用文本大小做为窗口大小
    private void OnFirstInit(GeometryChangedEvent evt)
    {
        tooltipLabel.UnregisterCallback<GeometryChangedEvent>(OnFirstInit);
        tipSize = new Vector2(instance.tooltipLabel.resolvedStyle.width, instance.tooltipLabel.resolvedStyle.height);
    }

    public override void OnClose()
    {
        instance = null;
    }

    public override void OnGUI(Rect rect)
    {
    }
}

public static class CustomTooltipExtensions
{
    public static void AddCustomTooltip(this VisualElement element, string tooltipText)
    {
        element.RegisterCallback<MouseEnterEvent>(evt =>
        {
            Rect rc = element.worldBound;
            // 使用 PopupWindow 会自动转换,就不需要在这里转换了
            // rc.position = rc.position + EditorWindow.mouseOverWindow.position.position;
            CustomTooltip.ShowTooltip(tooltipText, rc);
        });
        element.RegisterCallback<MouseLeaveEvent>(evt =>
        {
            CustomTooltip.HideTooltip();
        });
    }
}
<think>好的,我现在要帮助用户了解如何使用Unity UI Toolkit创建用户界面。首先,我需要回忆一下Unity UI Toolkit的基本概念和步骤。根据用户提供的引用内容,特别是引用[1]和引用[3],UI Toolkit使用USS和UXML,并且支持MVVM模式。不过用户可能只是刚开始接触,所以需要从基础开始。 首先,创建UI的流程大致包括创建UXML文件定义结构,USS文件定义样式,然后在脚本中加载这些文件。引用[3]提到了CreateGUI()方法和加载模板,所以应该要提到在编辑器里创建UXML和USS,然后在代码中使用克隆或加载的方法。 然后,需要分步骤讲解。比如第一步创建UI文档,第二步样式设计,第三步逻辑绑定。用户可能想知道如何将UI元素与代码交互,比如按钮点击事件。这里可能需要提到Query和事件监听,如引用[3]中的SetupButton()方法。 另外,用户可能对运行时UI和编辑器扩展感兴趣。根据引用[2],UI Toolkit适合大量UI界面,可能用户想同时了解这两种应用场景。需要区分如何在运行时创建UI,比如通过UIDocument组件,而编辑器扩展可能需要继承EditorWindow。 还要注意UXML的结构,比如使用VisualElement作为根,添加Button、Label等元素。USS类似于CSS,可以设置宽度、颜色等样式。这部分需要具体说明如何编写这些文件,以及如何关联到代码。 可能的问题点:UXML和USS的正确路径,确保被正确加载。还有事件绑定的方法,比如使用RegisterCallback。需要确认引用的内容是否有提到这些,比如引用[3]中的Clone()方法。 最后,根据用户提供的示例,需要生成相关问题,比如性能优化、动态加载、与uGUI的比较等,参考引用[2]和引用[1]中的内容。 总之,回答的结构应该是步骤分明的,先介绍基本流程,再详细每一步,然后给出示例代码,最后相关问题。确保引用正确的来源,比如引用[1]提到MVVM Toolkit,引用[3]提到CreateGUI()方法。</think>### 如何使用 Unity UI Toolkit 创建用户界面 #### 1. **基础概念与工具准备** Unity UI Toolkit 是 Unity 推出的新一代 UI 系统,支持运行时和编辑器界面开发。其核心文件类型包括: - **UXML**:用于定义 UI 结构和布局(类似 HTML)。 - **USS**:用于设置 UI 样式(类似 CSS)。 - **C# 脚本**:用于实现交互逻辑。 #### 2. **创建 UI 的步骤** **步骤 1:创建 UI 文档** 1. 在 Unity 编辑器中,右键点击项目窗口,选择 **Create > UI Toolkit > UI Document**,生成 `.uxml` 文件。 2. 双击 `.uxml` 文件,使用 UI Builder 进行可视化编辑,或直接编写 XML 代码定义元素(如按钮、文本标签)。 **示例 UXML 结构**: ```xml <ui:UXML xmlns:ui="UnityEngine.UIElements"> <VisualElement class="container"> <Label text="Hello UI Toolkit!" /> <Button text="Click Me" name="myButton" /> </VisualElement> </ui:UXML> ``` **步骤 2:添加样式(USS)** 1. 创建 `.uss` 文件,定义样式规则: ```css .container { width: 300px; height: 200px; background-color: #2D2D2D; } Button { margin-top: 20px; color: white; } ``` **步骤 3:绑定逻辑(C# 脚本)** 1. 创建 `UIDocument` 组件挂载到场景物体,关联 `.uxml` 文件。 2. 在脚本中加载 UI 元素并绑定事件: ```csharp using UnityEngine; using UnityEngine.UIElements; public class MyUIController : MonoBehaviour { private void OnEnable() { var uiDocument = GetComponent<UIDocument>(); VisualElement root = uiDocument.rootVisualElement; Button myButton = root.Q<Button>("myButton"); myButton.RegisterCallback<ClickEvent>(OnButtonClick); } private void OnButtonClick(ClickEvent evt) { Debug.Log("按钮被点击!"); } } ``` #### 3. **运行时与编辑器扩展** - **运行时 UI**:通过 `UIDocument` 组件加载,适用于游戏内界面[^3]。 - **编辑器扩展**:继承 `EditorWindow`,在 `CreateGUI()` 方法中加载 UI: ```csharp public class MyToolWindow : EditorWindow { [MenuItem("Tools/My Window")] public static void ShowWindow() { GetWindow<MyToolWindow>("My Tool"); } public void CreateGUI() { var uxml = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/UI/my_window.uxml"); uxml.CloneTree(rootVisualElement); } } ``` #### 4. **结合 MVVM 模式(进阶)** 通过引用[^1]提到的 **MVVM Toolkit**,可以将数据与 UI 解耦: 1. 定义 `ViewModel` 类管理数据。 2. 使用数据绑定将 UI 元素与 `ViewModel` 属性关联。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值