Skip to content

feat: 新增 UITKModule — 基于 UI Toolkit 的完整 UI 框架模块#270

Open
vvgool wants to merge 44 commits into
Alex-Rachel:mainfrom
vvgool:main
Open

feat: 新增 UITKModule — 基于 UI Toolkit 的完整 UI 框架模块#270
vvgool wants to merge 44 commits into
Alex-Rachel:mainfrom
vvgool:main

Conversation

@vvgool

@vvgool vvgool commented Jun 11, 2026

Copy link
Copy Markdown

概述

为 TEngine 新增基于 Unity UI Toolkit 的完整 UI 模块(UITKModule),与现有 UIModule (UGUI) 并行共存。

核心特性

  • 纯 C# 驱动:去 MonoBehaviour,Singleton + IUpdate 驱动
  • 分层 Panel 架构:5 层 UIDocument(Bottom/UI/Top/Tips/System),同层内节点顺序排深度
  • 完整生命周期:UITKWindow/UITKWidget,对齐现有 UIModule 的设计模式
  • 自动绑定[Q] + [OnClick] + [OnChange] Attribute,Editor 菜单生成 .bindgen.cs
  • MVVM 支持:BindableProperty/BindableCommand/BindableList + ViewModelBase
  • 虚拟化列表:UITKListView<T> 封装 Unity ListView,对齐 Widget 生命周期
  • 动画系统:内置 USS Transition 预设 + IUITKAnimationDriver 接口(预留 Tween)
  • 统一点击音效:IUITKClickSoundHandler 全局拦截,no-sound class 静音
  • 热更新兼容:UXML/USS 走 YooAsset AB,代码走 HybridCLR,生成代码是普通 C#
  • 主题换肤预留:USS 变量基础设施 + PanelSettings themeStyleSheet 接口

使用示例

[UIWindow(UILayer.UI, FullScreen = true)]
public partial class LoginWindow : UITKWindow
{
    [Q] Button btnLogin;
    [Q] Label lblTitle;
    [Q] TextField inputAccount;

    [OnClick] void OnBtnLogin() { /* 业务逻辑 */ }

    protected override void OnCreate()
    {
        lblTitle.text = "Welcome";
    }
}

// 打开
GameModule.UITK.ShowUIAsync<LoginWindow>();

文件结构

Assets/GameScripts/HotFix/GameLogic/Module/UITKModule/
├── Animation/    动画系统
├── Base/         UITKBase, UITKWindow, UITKWidget
├── Binding/      [Q], [OnClick], [Bind] 等 Attribute
├── Core/         UITKModule 单例 (Panel/Stack/Animation)
├── ListView/     虚拟化列表
├── MVVM/         BindableProperty/Command/List
└── Resource/     IUITKResourceLoader

Assets/Editor/UITKBindingGenerator/   Editor 代码生成工具
Assets/AssetRaw/UITK/                 UXML/USS 资源

兼容性

  • Unity 2022.3.63f2
  • 不修改现有 UIModule 任何代码
  • 共享 GameEvent / Timer / Resource 系统
  • GameModule.UITK 访问新模块

文档

  • 设计文档:docs/superpowers/specs/2026-06-11-uitk-module-design.md
  • Reference 文档:.claude/skills/tengine-dev/references/uitk-*.md

vvgool added 30 commits June 11, 2026 15:32
vvgool and others added 14 commits June 11, 2026 18:22
绑定生成器从「运行时反射 + 易泄漏 lambda」改为编译期生成对
UITKBase.Bind* helper 的调用,订阅/解绑使用同一委托实例,杜绝
`-= 新lambda` 永不解绑导致的内存泄漏。

主要改动:
- UITKBase 新增 BindLabel/BindField(同类型/converter)/BindCommand
  运行时 helper,统一登记解绑动作;移除旧 BindContext/UnbindContext。
- 生成器解析唯一 ViewModel 字段,按控件类型×属性类型×mode×converter
  选择绑定方式,类型不匹配/路径无效时编译期报错并跳过。
- 生命周期:OnCreate(构造 VM) 后自动 __UITKAutoBindMVVM,
  OnDestroy 前自动 __UITKAutoUnbindMVVM。
- VM 为 null 时输出 Warning 日志而非静默跳过,便于排查。

健壮性修复:
- Window/Widget/ListView 资源加载失败改为 try/catch + 返回 null,
  Window 弹栈回滚,避免 NRE 与卡死在栈中。
- 关闭动画期间被重新 Show 的竞态:新增 IsClosing 标志 + 动画后二次校验。
- InternalDestroy 幂等守卫,防止动画期间重复销毁。
- BindableList.AddRange/Clear 逐项触发增删事件;Clear 逆序保证 index 有效。
- BindableProperty 隐式转换 null 安全。
- UITKResourceLoader 改用 GameModule.Resource 统一访问。

新增 TestMvvmAutoBindWindow 全自动绑定测试(OneWay+format、TwoWay 同类型、
TwoWay+converter、命令),并同步更新 uitk-* 参考文档。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Alex-Rachel

Copy link
Copy Markdown
Owner

感谢PR,东西很不错,但UIToolKit比较小众 用的人确实少,这边建议先PR到仓库 TEngine.Extension https://github.com/Alex-Rachel/TEngine.Extension 后续等UIToolKit成熟后在并回主仓库。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants