尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

AI Agent从设计稿自动搭建FairyGUI UI结构:方案与踩坑记录

发布时间:2026/9/26 18:48:03

资讯中心
01
ARTICLE

AI Agent从设计稿自动搭建FairyGUI UI结构:方案与踩坑记录

AI Agent从设计稿自动搭建FairyGUI UI结构:方案与踩坑记录
先讲个真实经历。最近两个月我几乎把所有能挤出来的时间都用在了同一件事上让 AI Agent 替我把 FairyGUI 的 UI 结构从设计稿里“搭”出来。起因是新项目的界面量实在太大光一个主界面就三百多个节点手拼一遍得小一整天改一版需求又得半天起跳。人不是不能干但干这种活的时候脑子基本是闲置的——这就是典型的该交给 Agent 的场景。后来我把这条链路跑通之后从设计稿到 FairyGUI 工程里出现完整可发布的组件结构基本能做到分钟级。这篇文章就把我这段时间的完整思路、方案选型、代码细节、踩坑记录全部拆开讲适合正在用 FairyGUI 做游戏 UI、又被海量节点压得喘不过气的开发者和 UI 程序。想了解“Agent 到底怎么接进编辑器流程”的同学应该也能从这里找到一条可落地的路径。1. 先搞清楚手拼 FairyGUI 的痛点到底在哪不能一上来就聊 Agent得先弄清楚我们到底在抱怨什么。FairyGUI 本身是个很好的编辑器所见即所得资源依赖、控制器、关联系统都很成熟。但“好”是针对界面级操作而言的一旦面对成百上千个节点它和所有图形化编辑器一样有一个通病单个节点的操作效率很高批量结构的搭建效率极低。1.1 一次真实经历三百个节点的手工地狱前阵子我们做主城界面功能模块特别多顶部资源栏、角色信息区、任务追踪、活动入口、聊天框、底部导航、红点层……一个面板套一个面板最后打开组件树一看三百多个节点。我当时干了一件特别蠢也特别典型的事先对着设计稿把背景拖进来再一个个摆按钮、文本框调层级、调锚点、调关联。这些操作没有任何智力含量但就是费时间。更可怕的是改版设计稿换了布局整个组件树要重排关联关系断的断、错位的错位。那一周我加了好几天班干完只有一个感受这种活不应该由人来干。再说个更普遍的痛点团队里每个人拼出来的结构风格都不一样。有人喜欢把所有图片节点平铺在 displayList 里有人喜欢嵌套子组件命名习惯也不同这个叫btnStart那个叫startBtn。代码里引用、查找全靠猜。这其实不是操作效率问题是工程规范问题而人恰恰是最难保证规范一致的。1.2 Agent 能做什么把“搭结构”变成“写描述”Agent 不是来替代 FairyGUI 编辑器的它替代的是“人手拖拽”这个动作。核心逻辑很简单搭 UI 本质上是在描述一棵树——什么节点、什么类型、放在哪、多大、什么层级、跟谁关联。这本来就是大模型最擅长处理的“结构化输出”问题。我举个生活化类比。手拼 UI 就像手写 HTML 表格一个单元格一个单元格敲Agent 接手则像你用现成的组件库声明式写页面——同样是写代码但你在描述结构浏览器负责渲染。对应到 FairyGUI就是让 Agent 输出一份结构描述再通过转换器变成 FairyGUI 能识别的组件 XML最后进编辑器发布。但必须说清楚它的边界Agent 不能凭空生成美术资源。背景图、图标、字体这些还是得由美术准备好Agent 也不能替你搞定复杂交互逻辑控制器跳转、列表滚动、动效播放这些业务代码仍然要手写。它能做的是把“静态 UI 结构”这部分硬骨头啃下来而这部分恰恰是工作量的大头。2. Agent 接管 FairyGUI 的整套设计思路有了痛点第二步是设计整体方案。我见过不少同事一上来就让大模型直接写 FairyGUI 的工程文件写出来要么打不开要么编辑器一刷新全乱了。原因很简单FairyGUI 的工程文件格式是编辑器私有的不只是 XML还有资源索引、二进制元数据、版本兼容问题。让 LLM 直接操作这层东西等于让它写一个二进制私有格式它不是不能试但每次版本升级都会崩给你看。2.1 技术选型LLM 转换器 编辑器 CLI 三层结构我建议的架构是三层分离第一层是 LLM负责理解设计稿和需求输出一份与 FairyGUI 无关的纯结构描述第二层是一个本地转换器把这份结构描述翻译成 FairyGUI 组件 XML第三层是 FairyGUI 自己的命令行发布能力把 XML 吃进工程、生成资源包和绑定代码。为什么要中间夹一个转换器因为直接让 LLM 输出 XML 的幻觉率高得离谱。它可能编出根本不存在的属性名或者漏掉relation关联甚至把图片资源名写错。而 LLM 输出纯 JSON 结构时准确率高很多——字段少、约束清晰再用本地代码去映射、校验、兜底错误就能被拦截在进入工程之前。这就像让 AI 直接写 SQL 和让 AI 先生成查询条件、你再拿条件拼 SQL 的区别前者一步到位但不可控后者多一道闸门但每个环节都能验证。我的经验是永远让 LLM 输出可校验的中间产物而不是直接输出最终产物。2.2 数据流一条端到端的 UI 自动化管线整条管线的数据流我用文字走一遍你在脑子里过一遍就知道大概长什么样了。第一步设计稿和需求说明输入给 Agent如果是图片就配一个能看图的多模态模型如果是文字需求直接给 Prompt。第二步Agent 输出一份 UI 描述 JSON里面包含组件树、节点类型、坐标尺寸、文字内容、图片资源名、控制器状态列表。第三步本地脚本对 JSON 做校验——资源名是否存在于资源清单、坐标是否越界、必填字段有没有缺失。校验没过就带着错误信息丢回给 Agent 重新生成。第四步通过一版后转换器把 JSON 映射成 FairyGUI 组件 XML写进工程目录。第五步调用 FairyGUI 编辑器的命令行发布生成.bytes资源包和 Unity/Cocos 的绑定代码。第六步截一张预览图用视觉模型跟原设计稿做对比色差、布局差异、遮挡都比较一下有问题的再回流。这套链路看起来长但真正需要写的代码只有一个转换器加一堆校验脚本。核心耗时在 Agent 生成和人工审阅基本能做到对一个中等复杂度的面板五分钟内出第一版可用结构。2.3 关键决策先做半自动不做全自动我最初的想法很激进想让 Agent 生成完直接进工程。试了几天就老实了这一步必须保留人工审阅环节。原因有两个一是 Agent 偶尔会“合理但错误”地补全需求比如设计稿里一个没有文字的按钮它给编了一段文案虽然看起来没问题但产品肯定不认二是 FairyGUI 的层级叠放顺序很敏感显示列表从下到上就是渲染从下到上Agent 生成的顺序偶尔会和设计稿相反一眼看过去问题不大真跑起来按钮被背景挡住。所以最终的方案是Agent 负责生成人负责验收确认无误再发布进包。别觉得这样效率低人审一个面板结构只需要扫一眼树形图比从零开始手拼快了一个数量级。3. 核心实操从设计稿到 FairyGUI XML 的完整链路理论说完了上真东西。这一章我从协议、Prompt、映射、发布四个环节逐个拆确保你照着能做出来。3.1 第一步定义一份“UI 描述协议”要让 Agent 稳定输出最重要的是给它一个足够小的 JSON Schema。我定义的协议长这样这套字段经过几轮迭代已经能覆盖 FairyGUI 里绝大多数静态 UI 场景{ $schema: http://example.com/ui-description.schema.json, type: object, required: [name, width, height, children], properties: { name: { type: string, description: 组件名与设计稿命名一致 }, width: { type: integer, description: 设计宽度单位 px }, height: { type: integer, description: 设计高度单位 px }, children: { type: array, items: { type: object, required: [type, name, x, y, width, height], properties: { type: { type: string, enum: [image, text, button, list, graph, component, loader] }, name: { type: string }, x: { type: integer, description: 相对父节点左上角的 X 坐标 }, y: { type: integer }, width: { type: integer }, height: { type: integer }, pivot: { type: array, items: { type: number }, minItems: 2, maxItems: 2, description: 轴心点如 [0.5, 0.5] 表示中心点 }, resource: { type: string, description: 图片资源名必须来自资源清单 }, text: { type: string, description: 文本内容仅 text/button 使用 }, fontSize: { type: integer }, color: { type: string, pattern: ^#[0-9a-fA-F]{6}$ }, controllers: { type: array, items: { type: object, required: [name, pages], properties: { name: { type: string }, pages: { type: array, items: { type: object, required: [id, title], properties: { id: { type: integer }, title: { type: string } } } } } } }, children: { type: array, description: 嵌套子节点递归结构 } } } } } }这套协议有几个用心之处。第一type 字段用枚举值从源头堵住 Agent 发明新节点类型的可能。第二所有坐标都是相对父节点的整数不搞 float 不搞百分比让转换器逻辑简单Agent 也不容易算出小数。第三resource 字段明确标注“必须来自资源清单”这是在为后文说的资源防幻觉做准备。如果你有自己的特殊组件比如进度条、滑动条可以在枚举里加但一定要同时告诉 Agent 这些组件需要哪些额外字段。人话就是协议越小Agent 越稳。3.2 第二步Prompt 怎么写才能稳定输出有了 SchemaPrompt 就要把 AI 往这个 Schema 里赶。我试过几种写法最有效的是“角色限定 输出格式硬约束 少样本示例”三段式你是一名资深游戏 UI 结构工程师熟悉 FairyGUI 的组件体系和层级规则。 现在需要你根据用户提供的设计稿/需求描述输出一份 UI 结构 JSON。 硬性要求 1. 只能使用 JSON 格式输出不要包含任何解释性文字。 2. 必须严格遵循给定的 JSON Schema不得新增字段不得修改枚举值。 3. 所有 resource 字段的值必须从下面的资源清单中选择禁止编造资源名。 4. 坐标系为屏幕坐标原点在左上角x 向右为正y 向下为正。 5. 嵌套结构要合理同一层级的节点按渲染从底到顶的顺序排列。 6. 如果设计稿中存在某个图片或文字但资源清单中没有对应资源用 graph 节点占位并在输出末尾 REMARKS 字段中说明。 资源清单 bg_main, btn_start, btn_shop, icon_coin, txt_title, panel_bag, item_bg 以下是输出的 JSON 格式示例 { name: MainPanel, width: 1280, height: 720, children: [ ... ] } 请开始输出。这段 Prompt 里最关键的是第 5 条“渲染从底到顶”因为我踩过坑Agent 默认按照“从上往下读设计稿”的顺序排列子节点导致最底层的背景跑到了最上层。加上这一条之后层级顺序错误率明显下降。另外第 6 条也重要它给了 Agent 一条合法出路——资源缺失时用 graph 占位而不是硬编一个不存在的资源名。给 Agent 留退路比反复强调“不要乱编”有效得多。还有个小经验如果你接的是多模态模型最好把设计稿图片直接喂进去让它对着图输出坐标。但注意多模态模型的文字识别有时会把设计稿里的标注数字当成尺寸值这点在审阅时要重点检查。3.3 第三步JSON 到 FairyGUI XML 的映射与生成校验通过的 JSON 进入转换器这一步是把“协议描述”翻译成“编辑器语言”。核心映射关系我整理成了一张表JSON 字段FairyGUI XML 元素/属性说明type: imageimagesrc 属性填资源名type: texttexttext 属性填文案fontSize 映射 font-sizetype: buttonbutton内部往往带一个 title 文本节点type: listlist需要配合 item 模板 URLtype: graphgraph纯占位图形不绑资源x, yxy100,20相对父节点左上角width, heightsize200,80控件原始尺寸pivotpivot0.5,0.5轴心点附加 pivotAsAnchor 可选resourcesrcui://包名/资源名需要转换器拼上包名前缀controllerscontroller生成 controller 节点并填充 pageschildren 里的嵌套结构displayList内嵌套关键是层级顺序转换器生成的 XML 大概是这个味道拿一个简单的“背景 标题 开始按钮”做示例component size1280,720 controller namestate pages0,normal,1,selected/ displayList image namebg_main srcui://Game/bg_main size1280,720 xy0,0/ text nametxt_title font-size36 text欢迎回来 color#FFFFFF xy540,100 width200 height50 aligncenter/ button namebtn_start srcui://Game/btn_start xy540,300 width200 height80 relation targetbg_main sidealign_left width100%/ /button /displayList /component这里有两个转换器必须处理的细节。第一个是URL 前缀FairyGUI 里所有资源引用都是ui://包名/资源名格式JSON 里只写资源名转换器负责拼包名。第二个是relation 关联JSON 协议里没有直接体现我的做法是在转换器里写规则——如果某个节点有align需求就在 JSON 里加一个扩展字段转换器识别后生成relation。生成完 XML 后一定先去 FairyGUI 编辑器里手动打开这个组件看一眼再发布。为什么因为转换器只能保证语法正确不能保证视觉正确。编辑器里会直接暴露层级、坐标、透明度这些问题比你看代码快得多。3.4 第四步命令行发布与绑定代码生成XML 写进工程目录后接着要让它变成引擎里能用的东西。FairyGUI 编辑器提供命令行入口可以这样走FairyGUI-Editor.exe -publish 项目.fairy -package Game -output Assets/UI/Game具体参数名不同版本可能不一样以你装的编辑器版本为准。但思路是一致的不进编辑器 UI直接用命令行把 XML 编译成引擎侧可加载的资源包。这个能力特别适合接进 Jenkins 或本地脚本让整条 UI 生成链路完全无人值守。资源包发布之后FairyGUI 会为每个组件生成绑定代码比如 Unity 下的UI_MainPanel.cs。这里又轮到 Agent 出场了——它可以把这层包装类的生成也接管一部分。我常让它生成这种代码public class MainPanelView { public GComponent root { get; private set; } public GButton btnStart { get; private set; } public GTextField txtTitle { get; private set; } public MainPanelView(GComponent root) { this.root root; this.btnStart root.GetChild(btn_start).asButton; this.txtTitle root.GetChild(txt_title).asTextField; } }这类代码极其模式化人写纯属浪费时间Agent 生成又快又稳。而且只要你固定了命名规范Agent 生成出来的代码风格也会统一直接省掉代码 review 里最无聊的部分。4. 落地时我踩过的坑和排查方法理想很丰满现实里全是坑。这套流程我跑了一个多月踩的坑比预想的多得多而且很多坑特别隐蔽不实际操作根本想不到。我挑几个影响最大的展开说。4.1 坐标错乱pivot、锚点、关联三件套第一次用 Agent 生成复杂组件时我打开编辑器看到的画面是所有按钮都往右下角偏了半个身位文字全部跑到图片外面。排查了半天问题出在 pivot 上。FairyGUI 的坐标系统是“相对父组件左上角”但如果节点设置了 pivot它的 xy 定位就变成以 pivot 点为准。Agent 从设计稿里读到的坐标是基于左上角的它又不理解 pivot 语义于是把pivot0.5,0.5一加整个节点就偏移了。解决方法是普通静态节点不设 pivot只有需要旋转、缩放动效的节点才设。在协议里明确“默认无 pivot除非特别说明”并且在转换器里加一条强制规则——如果 JSON 里没有 pivot 字段XML 里坚决不输出 pivot。这个坑踩一次就够了。4.2 Agent 幻觉资源用资源清单做硬约束这是所有坑里出现频率最高的。Agent 会一本正经地引用一个根本不存在的图片资源名比如设计稿上有个背包按钮它直接输出resource: icon_bag但工程里的资源实际叫bag_icon。如果你没加保护转换器会生成一个 XMLFairyGUI 编译时直接报资源缺失整包发布失败。我前面提到的“资源清单喂给 Agent”就是干这个的。但光喂还不够转换器一定要做二次校验把 Agent 输出 JSON 里的 resource 字段全部抽取出来和本地资源清单做集合比对一旦发现未知资源直接中止流程并把错误反馈给 Agent 重试。整套过程会自动跑通常一次重试就能纠正。实测下来资源幻觉率能从三成压到 5% 以下。4.3 控制器状态漏生成运行时 UI 点不动还有一个低频但特别影响体验的问题Agent 生成的组件少了控制器。比如一个按钮需要 normal / pressed / selected 三个状态Agent 经常只给一个基础 image 节点忘了补控制器。结果运行时按钮点击没有反馈UI 看起来像死了一样。排查这种问题不能用肉眼看 XML得用脚本把所有button类型节点揪出来检查它是否至少有一个 controller。我在转换器校验环节加了一条规则button 节点必须有名为 state 的控制器且 pages 数量不少于 2否则视为校验失败。这样就把这个问题从“运行时才发现”提前到了“生成时就被拦截”。4.4 多个 Agent 并行时的冲突Git 才是隐形杀手当我把这套流程扩大到一个四人小组使用时又遇到新问题大家各自让 Agent 生成面板同时往同一个工程目录里写 XMLgit 冲突比手写代码还严重。因为 FairyGUI 工程里有个全局文件记录了所有资源的 GUID 和组件引用关系多人同时改这个文件几乎必然打架。我的应对方案是每个 UI 包拆分独立目录每个 Agent 任务只允许写自己负责的包合并时禁止并行写同一包另外把 FairyGUI 的工程文件全量纳入 Git 管理XML 是文本文件可以 diff、可以 review冲突至少能看见。这个教训是自动化生成不是免死金牌流程规范还是得人来定。4.5 常见问题速查表最后整理一张速查表遇到问题可以快速定位现象可能原因处理方式组件发布后资源缺失Agent 生成不存在的资源名转换器加资源清单比对 自动重试节点整体偏移pivot 与坐标语义冲突XML 不主动输出 pivot按需设置按钮点击无反馈缺少控制器 pages校验 button 节点的 controller 数量渲染层级不对displayList 顺序颠倒Prompt 明确“底到顶”顺序 人工审阅Git 冲突频繁多人同时改同一 UI 包包级隔离禁止并行写同一包文字内容被 Agent 妄改需求描述不完整在协议里增加“支持原文引用”字段XML 语法正确但编辑器打不开版本不兼容或字段拼错先打开编辑器看报错日志再转换器补兼容5. 给想接手这套流程的人四个实在建议前面把思路、代码、坑都讲完了最后说几句掏心窝子的建议。如果你真想把 Agent 接进 FairyGUI 流程别急着一步到位按下面这个节奏来。5.1 从组件级接管开始别一上来就整面板我最开始想直接生成整个主界面结果被层级、控制器、关联三座大山压得喘不过气。后来我退一步先让 Agent 只生成“单组件”——比如一个按钮、一个列表项、一个弹窗框架。这类结构简单字段少校验规则也好写。跑了几天发现效率确实高再逐步扩大到完整面板。步子太大容易扯着这点在 AI 流程里也一样适用。5.2 建一个自己的组件模板库Agent 生成的节点结构虽然对但风格不一定符合你们团队习惯。我的做法是把团队里既有的优质组件结构抽成模板写进转换器里。比如“标准按钮”就是“底图 文字 state 控制器”转换器遇到type: button时直接用模板生成而不是让 Agent 自由发挥。模板库越厚Agent 的自由度就应越小整体质量越可控。5.3 用失败案例反向喂给 Prompt每次 Agent 生成的组件被打回我都会把错误原因整理成一句话加进 Prompt。比如“列表项内部禁止嵌套滚动容器”“所有文本节点必须提供 color”。实践两三个星期后Agent 的生成质量会有肉眼可见的提升。这比换更大参数的模型管用因为问题往往出在领域细节而不是模型智力上。5.4 留一条手工兜底的快捷通道最后提醒一句别把手工能力丢掉。我做这套流程时仍然保留了“手动微调”的工作习惯——Agent 生成的组件进编辑器后我会快速拖一两个节点做微调。不是因为 Agent 不好用而是因为有些细节比如像素级对齐的视觉感受机器判断不如人眼敏感。工具的意义是让你把时间花在真正需要判断力的事情上而不是帮你彻底偷懒。我现在的工作习惯已经完全变了早上到公司先看设计稿更新把需求丢给 Agent它生成结构、自动校验、发布资源我这边做审阅和微调。原来一天手拼两三个面板的工作量现在能从容地做完一整层 UI 体系。这个方向未来还有很大空间比如把动效、状态机的生成也纳入进来但那又是另一篇文章了。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。