mcpField
U
unity-ui-development

unity-ui-development

github.com/josiahsiegel设计与 UI59104 次安装19 周前更新
代码仓库

关于 unity-ui-development

面向 Unity 开发者的 UI 开发技能,帮助选择和实现 UGUI 或 UI Toolkit。内容涵盖系统选择、布局、事件处理、样式、数据绑定及常见界面模式。

主要功能

  1. 01比较 UGUI 与 UI Toolkit
  2. 02Canvas 设置与 RectTransform 锚点
  3. 03布局和事件处理模式
  4. 04UXML、USS 与 C# 集成
  5. 05UI Toolkit 数据绑定

适用场景

  1. 01为 Unity 项目选择 UI 系统
  2. 02构建自适应菜单和 HUD
  3. 03使用 UI Toolkit 创建编辑器界面
  4. 04实现列表、弹窗或拖放交互

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill unity-ui-development

安装后在 Claude Code 中输入/unity-ui-development确认已加载。

详细介绍

Unity UI 开发

概述

Unity 提供两种 UI 系统:UGUI(成熟的、基于 GameObject 的系统)和 UI Toolkit(受 Web 技术启发的新型保留模式系统)。本技能介绍这两种系统、各自的适用场景以及实现模式。

选择 UI 系统

因素UGUIUI Toolkit
运行时 UI成熟、功能全面支持(Unity 2023+)
编辑器 UI不支持编辑器的主要系统
世界空间 UI出色(World Space Canvas)有限
动画/补间DOTween、Animator、LeanTweenUSS 过渡、C# 操作
样式按元素设置,手动配置USS 样式表(类似 CSS)
性能Canvas 较多时绘制调用开销较大保留模式,绘制调用开销较低
学习曲线对 Unity 开发者来说较低较高(类似 Web 的范式)
VR/AR支持良好世界空间支持有限

**建议:**世界空间 UI、VR/AR,以及需要最大程度兼容资源商店的项目,使用 UGUI。编辑器扩展、复杂的数据驱动 UI(列表、树形结构),以及基于 Unity 2023+ 的项目,使用 UI Toolkit。

UGUI(基于 Canvas 的 UI)

Canvas 设置
渲染模式用途备注
Screen Space - OverlayHUD、菜单始终显示在最上层,无需摄像机
Screen Space - Camera对 UI 进行后期处理指定渲染摄像机
World Space游戏内标牌、生命值条设置事件摄像机以支持交互

**性能规则:**将静态和动态 UI 分别放在不同的 Canvas 中。任何子元素发生变化时,Canvas 都会重建所有子元素。

RectTransform 锚点
Anchor presets control how elements resize with parent:
- Stretch-Stretch: Element fills parent (full-screen backgrounds)
- Center-Center: Fixed size at center (popup dialogs)
- Bottom-Left: Fixed corner position (minimap)
- Top-Stretch: Stretches horizontally, fixed at top (nav bar)

通过 RectTransform 锚点预设控件设置锚点(按住 Alt+Shift 还可同时设置轴心点和位置)。在代码中使用 anchorMin、anchorMax、offsetMin、offsetMax。

布局组件
组件用途
HorizontalLayoutGroup从左到右排列子元素
VerticalLayoutGroup从上到下排列子元素
GridLayoutGroup网格排列(物品栏槽位)
LayoutElement覆盖最小/首选/灵活尺寸
ContentSizeFitter根据内容自动调整尺寸
AspectRatioFitter保持宽高比

禁用 Layout.childForceExpandWidth/Height,以避免不需要的拉伸。

事件处理
using UnityEngine.UI;
using TMPro;

[SerializeField] Button startButton;
[SerializeField] TMP_InputField nameField;
[SerializeField] Slider volumeSlider;

void OnEnable()
{
    startButton.onClick.AddListener(OnStartClicked);
    nameField.onEndEdit.AddListener(OnNameChanged);
    volumeSlider.onValueChanged.AddListener(OnVolumeChanged);
}

void OnDisable()
{
    startButton.onClick.RemoveListener(OnStartClicked);
    nameField.onEndEdit.RemoveListener(OnNameChanged);
    volumeSlider.onValueChanged.RemoveListener(OnVolumeChanged);
}

务必在 OnDisable 中调用 RemoveListener,以防止泄漏和无效引用。

TextMeshPro

始终优先使用 TextMeshPro(TMP_Text、TextMeshProUGUI),而不是旧版 Text。出现提示时导入 TMP Essentials。使用富文本标签:<color=#FF0000>、<b>、<size=24>、<sprite=0> 来显示行内图标。

UI Toolkit(USS/UXML)

架构
UI Toolkit Stack:
  UXML  -- Structure (like HTML)
  USS   -- Styling (like CSS)
  C#    -- Logic (like JavaScript)
UXML 结构
<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <ui:VisualElement class="container">
        <ui:Label text="Player Stats" class="title" />
        <ui:ProgressBar name="health-bar" title="HP" high-value="100" />
        <ui:Button name="attack-btn" text="Attack" class="action-btn" />
        <ui:ListView name="inventory-list" />
    </ui:VisualElement>
</ui:UXML>
USS 样式
.container {
    flex-direction: column;
    padding: 10px;
    background-color: rgba(0, 0, 0, 0.8);
    border-radius: 8px;
}

.title {
    font-size: 24px;
    color: white;
    -unity-font-style: bold;
    margin-bottom: 10px;
}

.action-btn {
    height: 40px;
    background-color: #4CAF50;
    color: white;
    border-radius: 4px;
    transition-duration: 0.2s;
}

.action-btn:hover {
    background-color: #66BB6A;
    scale: 1.05 1.05;
}

USS 与 CSS 的主要区别:Unity 专用属性使用 -unity- 前缀。布局采用 Flexbox 模型(默认 flex-direction: column)。使用 transition-duration、transition-property 设置动画。

C# 集成
[RequireComponent(typeof(UIDocument))]
public class StatsUI : MonoBehaviour
{
    void OnEnable()
    {
        var root = GetComponent<UIDocument>().rootVisualElement;
        var healthBar = root.Q<ProgressBar>("health-bar");
        var attackBtn = root.Q<Button>("attack-btn");
        var inventory = root.Q<ListView>("inventory-list");

        attackBtn.RegisterCallback<ClickEvent>(OnAttack);
        healthBar.value = player.Health;

        // ListView binding
        inventory.makeItem = () => new Label();
        inventory.bindItem = (element, index) =>
            ((Label)element).text = items[index].Name;
        inventory.itemsSource = items;
    }
}

使用 Q<T>("name") 或 Q<T>(className: "class") 查询元素。使用 RegisterCallback<EventType> 注册回调。始终从 rootVisualElement 查询。

数据绑定(Unity 2023.2+)
// Runtime data binding with [CreateProperty] and INotifyBindablePropertyChanged
public class PlayerData : INotifyBindablePropertyChanged
{
    public event EventHandler<BindablePropertyChangedEventArgs> propertyChanged;
    private int _health;

    [CreateProperty]
    public int Health
    {
        get => _health;
        set { _health = value; Notify(); }
    }
    void Notify([CallerMemberName] string prop = "")
        => propertyChanged?.Invoke(this, new BindablePropertyChangedEventArgs(prop));
}

在 UXML 中通过 binding-path="Health" 绑定,或在 C# 中使用 element.SetBinding("value", new DataBinding { dataSourcePath = ... }) 绑定。

常见 UI 模式

模式UGUI 方案UI Toolkit 方案
弹出对话框启用/禁用子面板在视觉树中添加/移除
滚动列表ScrollRect + VerticalLayoutGroupListView(虚拟化)
拖放IBeginDragHandler、IDragHandler、IEndDragHandlerPointerManipulator
标签页系统Toggle 组 + 面板RadioButtonGroup + 显示切换
工具提示跟随光标的面板Manipulator + VisualElement 定位
屏幕淡入淡出对 CanvasGroup.alpha 进行补间USS 不透明度过渡

更多资源

参考文件
  • references/ugui-patterns.md —— 高级 UGUI 模式:滚动优化、动态布局、世界空间交互、本地化、安全区域处理、屏幕适配
  • references/ui-toolkit-advanced.md —— 自定义控件、精通 ListView/TreeView、自定义操作器、编辑器 UI 集成、主题设置、响应式布局

评论

支持 Markdown