UI 代码生成器 (UI Builder)

为了提高 UI 开发效率,Fink Framework 提供了一个可视化的 UI 代码生成器 (UI Builder)
它可以一键生成遵循框架规范的 .cs 脚本和 .prefab 预制体,并自动完成控件的绑定逻辑。

功能亮点:

  • 自动生成继承自 BasePanel 的脚本
  • 自动处理 GetControl 绑定代码(无需手动写 Find 或拖拽)
  • 自动创建标准的 UI 预制体结构
  • 支持 TextMeshPro (TMP) 与传统 UGUI 切换
  • 可选生成示例控件(按钮、输入框、开关等)以供快速测试

1. 打开工具

在 Unity 编辑器菜单栏中选择:
Fink Framework -> 创建 UI 面板


2. 面板设置说明

打开窗口后,你将看到以下配置项:

2.1 面板设置 (Panel Settings)

选项说明示例 / 默认值
面板名称 (Panel Name)也就是类名。建议以 Panel 结尾,首字母大写LoginPanel / BagPanel
代码输出路径生成 .cs 文件的位置。工具会根据此路径自动计算 Namespace。Assets/Scripts/UI/Panels
预制体输出路径生成 .prefab 文件的位置。注意: 如果使用默认的 UIManager.ShowPanel,建议保持在 Resources 目录下。Assets/Resources/UI/Panels

关于命名空间 (Namespace) 的生成规则:
工具会自动检测路径中 Assets/Scripts/ 之后的部分作为命名空间。
例如路径为 Assets/Scripts/Game/UI/Login,则生成的命名空间为 Game.UI.Login

2.2 示例控件 (Example UI)

为了方便快速搭建原型,你可以勾选生成一些基础控件:

  • 是否使用 TextMeshPro
    • ✅ 勾选:使用 TMP_InputFieldTextMeshProUGUI
    • ⬜ 不勾选:使用传统 UGUI 的 InputFieldText
  • 添加示例按钮 / 输入框 / Toggle / Slider
    • 勾选后,生成的预制体中会包含这些 UI 元素,且生成的脚本中会自动包含对应的 GetControl 代码和事件响应逻辑示例。

3. 使用流程

第一步:点击创建

配置好名称和路径后,点击底部的 “创建 UI 面板” 按钮。

第二步:等待编译

点击后,Unity 会立即触发 Recompile (重新编译)

注意:此时请勿操作编辑器。工具需要在脚本编译通过后,通过反射获取脚本类型,才能将其挂载到预制体上。

第三步:完成

编译结束后,工具会自动:

  1. Resources 路径下生成 .prefab 文件。
  2. 创建根节点、背景图 (Background)、内容父节点 (Content)。
  3. 将新生成的脚本挂载到预制体根节点上。
  4. 如果勾选了示例控件,预制体里会出现对应的 UI 元素。
  5. 在 Project 窗口中高亮显示新创建的预制体。

4. 生成产物解析

4.1 预制体结构

生成的预制体默认结构如下:

LoginPanel (Root, 挂载 LoginPanel.cs)
├── Background (全屏半透明白色背景, 用于阻挡射线)
└── Content (UI 内容容器, 挂载 VerticalLayoutGroup 用于示例排列)
    ├── DemoButton (如果勾选)
    ├── DemoInput (如果勾选)
    └── ...

4.2 脚本结构

生成的脚本会自动包含以下内容:

using FinkFramework.Runtime.UI.Base;
// ... 其他引用

namespace Game.UI.Panels
{
    public class LoginPanel : BasePanel
    {
        // 1. 自动生成的字段
        private Button DemoButton;
        
        protected override void Awake()
        {
            base.Awake();

            // 2. 自动生成的绑定逻辑
            // 名字与预制体节点名严格对应
            DemoButton = GetControl<Button>("DemoButton");
        }

        public override void ShowMe()
        {
            // 首次显示逻辑
        }

        // ... 生命周期 ...

        // 3. 自动生成的事件示例
        protected override void ClickBtn(string btnName)
        {
            if (btnName == "DemoButton")
            {
                LogUtil.Info("UI", "点击了 DemoButton");
            }
        }
    }
}

5. 后续开发建议

  1. 移动控件: 你可以随意调整 Content 下控件的位置,或者删除自动生成的示例控件。 关键点:只要控件还在预制体子节点中,且名字与代码中 GetControl 的字符串一致,BasePanel 就能自动找到它。

  2. 添加新控件: 在预制体中添加新按钮(例如命名为 BtnClose)后,只需在脚本中添加:

    // 只有需要代码控制时才需要获取引用,否则直接在 ClickBtn 处理即可
    // private Button btnClose; 
    
    protected override void ClickBtn(string btnName) {
        if (btnName == "BtnClose") HidePanel();
    }
    
  3. 修改模板: 如果你想修改生成代码的默认模板(例如增加版权声明、修改默认注释),可以修改文件:
    Assets/FinkFramework/Editor/Resources/UI/template_ui_panel.txt


6. 常见问题

Q: 创建完没有生成 Prefab?
A: 请检查 Console 是否有报错。通常是因为编译失败(代码有错误)导致工具无法在编译后继续执行生成 Prefab 的逻辑。请修复代码错误后重新点击创建。

Q: 为什么生成的脚本没有 namespace?
A: 如果你的脚本路径不在 Assets/Scripts/ 目录下,工具可能无法正确解析命名空间。请遵循标准的工程目录结构。

Q: 预制体路径一定要在 Resources 下吗?
A: 不一定。但如果你使用 UIManager.Instance.ShowPanel<T>() 这种不带路径参数的重载方法,框架默认会去 Resources/UI/Panels/ 下寻找。如果你修改了路径,加载时需要手动传入 fullPath