計(jì)稿自動(dòng)搭建FairyGUI UI結(jié)構(gòu):方案與踩坑記錄)
先講個(gè)真實(shí)經(jīng)歷。最近兩個(gè)月我?guī)缀醢阉心軘D出來的時(shí)間都用在了同一件事上讓 AI Agent 替我把 FairyGUI 的 UI 結(jié)構(gòu)從設(shè)計(jì)稿里“搭”出來。起因是新項(xiàng)目的界面量實(shí)在太大光一個(gè)主界面就三百多個(gè)節(jié)點(diǎn)手拼一遍得小一整天改一版需求又得半天起跳。人不是不能干但干這種活的時(shí)候腦子基本是閑置的——這就是典型的該交給 Agent 的場(chǎng)景。后來我把這條鏈路跑通之后從設(shè)計(jì)稿到 FairyGUI 工程里出現(xiàn)完整可發(fā)布的組件結(jié)構(gòu)基本能做到分鐘級(jí)。這篇文章就把我這段時(shí)間的完整思路、方案選型、代碼細(xì)節(jié)、踩坑記錄全部拆開講適合正在用 FairyGUI 做游戲 UI、又被海量節(jié)點(diǎn)壓得喘不過氣的開發(fā)者和 UI 程序。想了解“Agent 到底怎么接進(jìn)編輯器流程”的同學(xué)應(yīng)該也能從這里找到一條可落地的路徑。1. 先搞清楚手拼 FairyGUI 的痛點(diǎn)到底在哪不能一上來就聊 Agent得先弄清楚我們到底在抱怨什么。FairyGUI 本身是個(gè)很好的編輯器所見即所得資源依賴、控制器、關(guān)聯(lián)系統(tǒng)都很成熟。但“好”是針對(duì)界面級(jí)操作而言的一旦面對(duì)成百上千個(gè)節(jié)點(diǎn)它和所有圖形化編輯器一樣有一個(gè)通病單個(gè)節(jié)點(diǎn)的操作效率很高批量結(jié)構(gòu)的搭建效率極低。1.1 一次真實(shí)經(jīng)歷三百個(gè)節(jié)點(diǎn)的手工地獄前陣子我們做主城界面功能模塊特別多頂部資源欄、角色信息區(qū)、任務(wù)追蹤、活動(dòng)入口、聊天框、底部導(dǎo)航、紅點(diǎn)層……一個(gè)面板套一個(gè)面板最后打開組件樹一看三百多個(gè)節(jié)點(diǎn)。我當(dāng)時(shí)干了一件特別蠢也特別典型的事先對(duì)著設(shè)計(jì)稿把背景拖進(jìn)來再一個(gè)個(gè)擺按鈕、文本框調(diào)層級(jí)、調(diào)錨點(diǎn)、調(diào)關(guān)聯(lián)。這些操作沒有任何智力含量但就是費(fèi)時(shí)間。更可怕的是改版設(shè)計(jì)稿換了布局整個(gè)組件樹要重排關(guān)聯(lián)關(guān)系斷的斷、錯(cuò)位的錯(cuò)位。那一周我加了好幾天班干完只有一個(gè)感受這種活不應(yīng)該由人來干。再說個(gè)更普遍的痛點(diǎn)團(tuán)隊(duì)里每個(gè)人拼出來的結(jié)構(gòu)風(fēng)格都不一樣。有人喜歡把所有圖片節(jié)點(diǎn)平鋪在 displayList 里有人喜歡嵌套子組件命名習(xí)慣也不同這個(gè)叫btnStart那個(gè)叫startBtn。代碼里引用、查找全靠猜。這其實(shí)不是操作效率問題是工程規(guī)范問題而人恰恰是最難保證規(guī)范一致的。1.2 Agent 能做什么把“搭結(jié)構(gòu)”變成“寫描述”Agent 不是來替代 FairyGUI 編輯器的它替代的是“人手拖拽”這個(gè)動(dòng)作。核心邏輯很簡(jiǎn)單搭 UI 本質(zhì)上是在描述一棵樹——什么節(jié)點(diǎn)、什么類型、放在哪、多大、什么層級(jí)、跟誰關(guān)聯(lián)。這本來就是大模型最擅長處理的“結(jié)構(gòu)化輸出”問題。我舉個(gè)生活化類比。手拼 UI 就像手寫 HTML 表格一個(gè)單元格一個(gè)單元格敲Agent 接手則像你用現(xiàn)成的組件庫聲明式寫頁面——同樣是寫代碼但你在描述結(jié)構(gòu)瀏覽器負(fù)責(zé)渲染。對(duì)應(yīng)到 FairyGUI就是讓 Agent 輸出一份結(jié)構(gòu)描述再通過轉(zhuǎn)換器變成 FairyGUI 能識(shí)別的組件 XML最后進(jìn)編輯器發(fā)布。但必須說清楚它的邊界Agent 不能憑空生成美術(shù)資源。背景圖、圖標(biāo)、字體這些還是得由美術(shù)準(zhǔn)備好Agent 也不能替你搞定復(fù)雜交互邏輯控制器跳轉(zhuǎn)、列表滾動(dòng)、動(dòng)效播放這些業(yè)務(wù)代碼仍然要手寫。它能做的是把“靜態(tài) UI 結(jié)構(gòu)”這部分硬骨頭啃下來而這部分恰恰是工作量的大頭。2. Agent 接管 FairyGUI 的整套設(shè)計(jì)思路有了痛點(diǎn)第二步是設(shè)計(jì)整體方案。我見過不少同事一上來就讓大模型直接寫 FairyGUI 的工程文件寫出來要么打不開要么編輯器一刷新全亂了。原因很簡(jiǎn)單FairyGUI 的工程文件格式是編輯器私有的不只是 XML還有資源索引、二進(jìn)制元數(shù)據(jù)、版本兼容問題。讓 LLM 直接操作這層?xùn)|西等于讓它寫一個(gè)二進(jìn)制私有格式它不是不能試但每次版本升級(jí)都會(huì)崩給你看。2.1 技術(shù)選型LLM 轉(zhuǎn)換器 編輯器 CLI 三層結(jié)構(gòu)我建議的架構(gòu)是三層分離第一層是 LLM負(fù)責(zé)理解設(shè)計(jì)稿和需求輸出一份與 FairyGUI 無關(guān)的純結(jié)構(gòu)描述第二層是一個(gè)本地轉(zhuǎn)換器把這份結(jié)構(gòu)描述翻譯成 FairyGUI 組件 XML第三層是 FairyGUI 自己的命令行發(fā)布能力把 XML 吃進(jìn)工程、生成資源包和綁定代碼。為什么要中間夾一個(gè)轉(zhuǎn)換器因?yàn)橹苯幼?LLM 輸出 XML 的幻覺率高得離譜。它可能編出根本不存在的屬性名或者漏掉relation關(guān)聯(lián)甚至把圖片資源名寫錯(cuò)。而 LLM 輸出純 JSON 結(jié)構(gòu)時(shí)準(zhǔn)確率高很多——字段少、約束清晰再用本地代碼去映射、校驗(yàn)、兜底錯(cuò)誤就能被攔截在進(jìn)入工程之前。這就像讓 AI 直接寫 SQL 和讓 AI 先生成查詢條件、你再拿條件拼 SQL 的區(qū)別前者一步到位但不可控后者多一道閘門但每個(gè)環(huán)節(jié)都能驗(yàn)證。我的經(jīng)驗(yàn)是永遠(yuǎn)讓 LLM 輸出可校驗(yàn)的中間產(chǎn)物而不是直接輸出最終產(chǎn)物。2.2 數(shù)據(jù)流一條端到端的 UI 自動(dòng)化管線整條管線的數(shù)據(jù)流我用文字走一遍你在腦子里過一遍就知道大概長什么樣了。第一步設(shè)計(jì)稿和需求說明輸入給 Agent如果是圖片就配一個(gè)能看圖的多模態(tài)模型如果是文字需求直接給 Prompt。第二步Agent 輸出一份 UI 描述 JSON里面包含組件樹、節(jié)點(diǎn)類型、坐標(biāo)尺寸、文字內(nèi)容、圖片資源名、控制器狀態(tài)列表。第三步本地腳本對(duì) JSON 做校驗(yàn)——資源名是否存在于資源清單、坐標(biāo)是否越界、必填字段有沒有缺失。校驗(yàn)沒過就帶著錯(cuò)誤信息丟回給 Agent 重新生成。第四步通過一版后轉(zhuǎn)換器把 JSON 映射成 FairyGUI 組件 XML寫進(jìn)工程目錄。第五步調(diào)用 FairyGUI 編輯器的命令行發(fā)布生成.bytes資源包和 Unity/Cocos 的綁定代碼。第六步截一張預(yù)覽圖用視覺模型跟原設(shè)計(jì)稿做對(duì)比色差、布局差異、遮擋都比較一下有問題的再回流。這套鏈路看起來長但真正需要寫的代碼只有一個(gè)轉(zhuǎn)換器加一堆校驗(yàn)?zāi)_本。核心耗時(shí)在 Agent 生成和人工審閱基本能做到對(duì)一個(gè)中等復(fù)雜度的面板五分鐘內(nèi)出第一版可用結(jié)構(gòu)。2.3 關(guān)鍵決策先做半自動(dòng)不做全自動(dòng)我最初的想法很激進(jìn)想讓 Agent 生成完直接進(jìn)工程。試了幾天就老實(shí)了這一步必須保留人工審閱環(huán)節(jié)。原因有兩個(gè)一是 Agent 偶爾會(huì)“合理但錯(cuò)誤”地補(bǔ)全需求比如設(shè)計(jì)稿里一個(gè)沒有文字的按鈕它給編了一段文案雖然看起來沒問題但產(chǎn)品肯定不認(rèn)二是 FairyGUI 的層級(jí)疊放順序很敏感顯示列表從下到上就是渲染從下到上Agent 生成的順序偶爾會(huì)和設(shè)計(jì)稿相反一眼看過去問題不大真跑起來按鈕被背景擋住。所以最終的方案是Agent 負(fù)責(zé)生成人負(fù)責(zé)驗(yàn)收確認(rèn)無誤再發(fā)布進(jìn)包。別覺得這樣效率低人審一個(gè)面板結(jié)構(gòu)只需要掃一眼樹形圖比從零開始手拼快了一個(gè)數(shù)量級(jí)。3. 核心實(shí)操從設(shè)計(jì)稿到 FairyGUI XML 的完整鏈路理論說完了上真東西。這一章我從協(xié)議、Prompt、映射、發(fā)布四個(gè)環(huán)節(jié)逐個(gè)拆確保你照著能做出來。3.1 第一步定義一份“UI 描述協(xié)議”要讓 Agent 穩(wěn)定輸出最重要的是給它一個(gè)足夠小的 JSON Schema。我定義的協(xié)議長這樣這套字段經(jīng)過幾輪迭代已經(jīng)能覆蓋 FairyGUI 里絕大多數(shù)靜態(tài) UI 場(chǎng)景{ $schema: http://example.com/ui-description.schema.json, type: object, required: [name, width, height, children], properties: { name: { type: string, description: 組件名與設(shè)計(jì)稿命名一致 }, width: { type: integer, description: 設(shè)計(jì)寬度單位 px }, height: { type: integer, description: 設(shè)計(jì)高度單位 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: 相對(duì)父節(jié)點(diǎn)左上角的 X 坐標(biāo) }, y: { type: integer }, width: { type: integer }, height: { type: integer }, pivot: { type: array, items: { type: number }, minItems: 2, maxItems: 2, description: 軸心點(diǎn)如 [0.5, 0.5] 表示中心點(diǎn) }, resource: { type: string, description: 圖片資源名必須來自資源清單 }, text: { type: string, description: 文本內(nèi)容僅 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: 嵌套子節(jié)點(diǎn)遞歸結(jié)構(gòu) } } } } } }這套協(xié)議有幾個(gè)用心之處。第一type 字段用枚舉值從源頭堵住 Agent 發(fā)明新節(jié)點(diǎn)類型的可能。第二所有坐標(biāo)都是相對(duì)父節(jié)點(diǎn)的整數(shù)不搞 float 不搞百分比讓轉(zhuǎn)換器邏輯簡(jiǎn)單Agent 也不容易算出小數(shù)。第三resource 字段明確標(biāo)注“必須來自資源清單”這是在為后文說的資源防幻覺做準(zhǔn)備。如果你有自己的特殊組件比如進(jìn)度條、滑動(dòng)條可以在枚舉里加但一定要同時(shí)告訴 Agent 這些組件需要哪些額外字段。人話就是協(xié)議越小Agent 越穩(wěn)。3.2 第二步Prompt 怎么寫才能穩(wěn)定輸出有了 SchemaPrompt 就要把 AI 往這個(gè) Schema 里趕。我試過幾種寫法最有效的是“角色限定 輸出格式硬約束 少樣本示例”三段式你是一名資深游戲 UI 結(jié)構(gòu)工程師熟悉 FairyGUI 的組件體系和層級(jí)規(guī)則。 現(xiàn)在需要你根據(jù)用戶提供的設(shè)計(jì)稿/需求描述輸出一份 UI 結(jié)構(gòu) JSON。 硬性要求 1. 只能使用 JSON 格式輸出不要包含任何解釋性文字。 2. 必須嚴(yán)格遵循給定的 JSON Schema不得新增字段不得修改枚舉值。 3. 所有 resource 字段的值必須從下面的資源清單中選擇禁止編造資源名。 4. 坐標(biāo)系為屏幕坐標(biāo)原點(diǎn)在左上角x 向右為正y 向下為正。 5. 嵌套結(jié)構(gòu)要合理同一層級(jí)的節(jié)點(diǎn)按渲染從底到頂?shù)捻樞蚺帕小?6. 如果設(shè)計(jì)稿中存在某個(gè)圖片或文字但資源清單中沒有對(duì)應(yīng)資源用 graph 節(jié)點(diǎn)占位并在輸出末尾 REMARKS 字段中說明。 資源清單 bg_main, btn_start, btn_shop, icon_coin, txt_title, panel_bag, item_bg 以下是輸出的 JSON 格式示例 { name: MainPanel, width: 1280, height: 720, children: [ ... ] } 請(qǐng)開始輸出。這段 Prompt 里最關(guān)鍵的是第 5 條“渲染從底到頂”因?yàn)槲也冗^坑Agent 默認(rèn)按照“從上往下讀設(shè)計(jì)稿”的順序排列子節(jié)點(diǎn)導(dǎo)致最底層的背景跑到了最上層。加上這一條之后層級(jí)順序錯(cuò)誤率明顯下降。另外第 6 條也重要它給了 Agent 一條合法出路——資源缺失時(shí)用 graph 占位而不是硬編一個(gè)不存在的資源名。給 Agent 留退路比反復(fù)強(qiáng)調(diào)“不要亂編”有效得多。還有個(gè)小經(jīng)驗(yàn)如果你接的是多模態(tài)模型最好把設(shè)計(jì)稿圖片直接喂進(jìn)去讓它對(duì)著圖輸出坐標(biāo)。但注意多模態(tài)模型的文字識(shí)別有時(shí)會(huì)把設(shè)計(jì)稿里的標(biāo)注數(shù)字當(dāng)成尺寸值這點(diǎn)在審閱時(shí)要重點(diǎn)檢查。3.3 第三步JSON 到 FairyGUI XML 的映射與生成校驗(yàn)通過的 JSON 進(jìn)入轉(zhuǎn)換器這一步是把“協(xié)議描述”翻譯成“編輯器語言”。核心映射關(guān)系我整理成了一張表JSON 字段FairyGUI XML 元素/屬性說明type: imageimagesrc 屬性填資源名type: texttexttext 屬性填文案fontSize 映射 font-sizetype: buttonbutton內(nèi)部往往帶一個(gè) title 文本節(jié)點(diǎn)type: listlist需要配合 item 模板 URLtype: graphgraph純占位圖形不綁資源x, yxy100,20相對(duì)父節(jié)點(diǎn)左上角width, heightsize200,80控件原始尺寸pivotpivot0.5,0.5軸心點(diǎn)附加 pivotAsAnchor 可選resourcesrcui://包名/資源名需要轉(zhuǎn)換器拼上包名前綴controllerscontroller生成 controller 節(jié)點(diǎn)并填充 pageschildren 里的嵌套結(jié)構(gòu)displayList內(nèi)嵌套關(guān)鍵是層級(jí)順序轉(zhuǎn)換器生成的 XML 大概是這個(gè)味道拿一個(gè)簡(jiǎn)單的“背景 標(biāo)題 開始按鈕”做示例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這里有兩個(gè)轉(zhuǎn)換器必須處理的細(xì)節(jié)。第一個(gè)是URL 前綴FairyGUI 里所有資源引用都是ui://包名/資源名格式JSON 里只寫資源名轉(zhuǎn)換器負(fù)責(zé)拼包名。第二個(gè)是relation 關(guān)聯(lián)JSON 協(xié)議里沒有直接體現(xiàn)我的做法是在轉(zhuǎn)換器里寫規(guī)則——如果某個(gè)節(jié)點(diǎn)有align需求就在 JSON 里加一個(gè)擴(kuò)展字段轉(zhuǎn)換器識(shí)別后生成relation。生成完 XML 后一定先去 FairyGUI 編輯器里手動(dòng)打開這個(gè)組件看一眼再發(fā)布。為什么因?yàn)檗D(zhuǎn)換器只能保證語法正確不能保證視覺正確。編輯器里會(huì)直接暴露層級(jí)、坐標(biāo)、透明度這些問題比你看代碼快得多。3.4 第四步命令行發(fā)布與綁定代碼生成XML 寫進(jìn)工程目錄后接著要讓它變成引擎里能用的東西。FairyGUI 編輯器提供命令行入口可以這樣走FairyGUI-Editor.exe -publish 項(xiàng)目.fairy -package Game -output Assets/UI/Game具體參數(shù)名不同版本可能不一樣以你裝的編輯器版本為準(zhǔn)。但思路是一致的不進(jìn)編輯器 UI直接用命令行把 XML 編譯成引擎?zhèn)瓤杉虞d的資源包。這個(gè)能力特別適合接進(jìn) Jenkins 或本地腳本讓整條 UI 生成鏈路完全無人值守。資源包發(fā)布之后FairyGUI 會(huì)為每個(gè)組件生成綁定代碼比如 Unity 下的UI_MainPanel.cs。這里又輪到 Agent 出場(chǎng)了——它可以把這層包裝類的生成也接管一部分。我常讓它生成這種代碼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; } }這類代碼極其模式化人寫純屬浪費(fèi)時(shí)間Agent 生成又快又穩(wěn)。而且只要你固定了命名規(guī)范Agent 生成出來的代碼風(fēng)格也會(huì)統(tǒng)一直接省掉代碼 review 里最無聊的部分。4. 落地時(shí)我踩過的坑和排查方法理想很豐滿現(xiàn)實(shí)里全是坑。這套流程我跑了一個(gè)多月踩的坑比預(yù)想的多得多而且很多坑特別隱蔽不實(shí)際操作根本想不到。我挑幾個(gè)影響最大的展開說。4.1 坐標(biāo)錯(cuò)亂pivot、錨點(diǎn)、關(guān)聯(lián)三件套第一次用 Agent 生成復(fù)雜組件時(shí)我打開編輯器看到的畫面是所有按鈕都往右下角偏了半個(gè)身位文字全部跑到圖片外面。排查了半天問題出在 pivot 上。FairyGUI 的坐標(biāo)系統(tǒng)是“相對(duì)父組件左上角”但如果節(jié)點(diǎn)設(shè)置了 pivot它的 xy 定位就變成以 pivot 點(diǎn)為準(zhǔn)。Agent 從設(shè)計(jì)稿里讀到的坐標(biāo)是基于左上角的它又不理解 pivot 語義于是把pivot0.5,0.5一加整個(gè)節(jié)點(diǎn)就偏移了。解決方法是普通靜態(tài)節(jié)點(diǎn)不設(shè) pivot只有需要旋轉(zhuǎn)、縮放動(dòng)效的節(jié)點(diǎn)才設(shè)。在協(xié)議里明確“默認(rèn)無 pivot除非特別說明”并且在轉(zhuǎn)換器里加一條強(qiáng)制規(guī)則——如果 JSON 里沒有 pivot 字段XML 里堅(jiān)決不輸出 pivot。這個(gè)坑踩一次就夠了。4.2 Agent 幻覺資源用資源清單做硬約束這是所有坑里出現(xiàn)頻率最高的。Agent 會(huì)一本正經(jīng)地引用一個(gè)根本不存在的圖片資源名比如設(shè)計(jì)稿上有個(gè)背包按鈕它直接輸出resource: icon_bag但工程里的資源實(shí)際叫bag_icon。如果你沒加保護(hù)轉(zhuǎn)換器會(huì)生成一個(gè) XMLFairyGUI 編譯時(shí)直接報(bào)資源缺失整包發(fā)布失敗。我前面提到的“資源清單喂給 Agent”就是干這個(gè)的。但光喂還不夠轉(zhuǎn)換器一定要做二次校驗(yàn)把 Agent 輸出 JSON 里的 resource 字段全部抽取出來和本地資源清單做集合比對(duì)一旦發(fā)現(xiàn)未知資源直接中止流程并把錯(cuò)誤反饋給 Agent 重試。整套過程會(huì)自動(dòng)跑通常一次重試就能糾正。實(shí)測(cè)下來資源幻覺率能從三成壓到 5% 以下。4.3 控制器狀態(tài)漏生成運(yùn)行時(shí) UI 點(diǎn)不動(dòng)還有一個(gè)低頻但特別影響體驗(yàn)的問題Agent 生成的組件少了控制器。比如一個(gè)按鈕需要 normal / pressed / selected 三個(gè)狀態(tài)Agent 經(jīng)常只給一個(gè)基礎(chǔ) image 節(jié)點(diǎn)忘了補(bǔ)控制器。結(jié)果運(yùn)行時(shí)按鈕點(diǎn)擊沒有反饋UI 看起來像死了一樣。排查這種問題不能用肉眼看 XML得用腳本把所有button類型節(jié)點(diǎn)揪出來檢查它是否至少有一個(gè) controller。我在轉(zhuǎn)換器校驗(yàn)環(huán)節(jié)加了一條規(guī)則button 節(jié)點(diǎn)必須有名為 state 的控制器且 pages 數(shù)量不少于 2否則視為校驗(yàn)失敗。這樣就把這個(gè)問題從“運(yùn)行時(shí)才發(fā)現(xiàn)”提前到了“生成時(shí)就被攔截”。4.4 多個(gè) Agent 并行時(shí)的沖突Git 才是隱形殺手當(dāng)我把這套流程擴(kuò)大到一個(gè)四人小組使用時(shí)又遇到新問題大家各自讓 Agent 生成面板同時(shí)往同一個(gè)工程目錄里寫 XMLgit 沖突比手寫代碼還嚴(yán)重。因?yàn)?FairyGUI 工程里有個(gè)全局文件記錄了所有資源的 GUID 和組件引用關(guān)系多人同時(shí)改這個(gè)文件幾乎必然打架。我的應(yīng)對(duì)方案是每個(gè) UI 包拆分獨(dú)立目錄每個(gè) Agent 任務(wù)只允許寫自己負(fù)責(zé)的包合并時(shí)禁止并行寫同一包另外把 FairyGUI 的工程文件全量納入 Git 管理XML 是文本文件可以 diff、可以 review沖突至少能看見。這個(gè)教訓(xùn)是自動(dòng)化生成不是免死金牌流程規(guī)范還是得人來定。4.5 常見問題速查表最后整理一張速查表遇到問題可以快速定位現(xiàn)象可能原因處理方式組件發(fā)布后資源缺失Agent 生成不存在的資源名轉(zhuǎn)換器加資源清單比對(duì) 自動(dòng)重試節(jié)點(diǎn)整體偏移pivot 與坐標(biāo)語義沖突XML 不主動(dòng)輸出 pivot按需設(shè)置按鈕點(diǎn)擊無反饋缺少控制器 pages校驗(yàn) button 節(jié)點(diǎn)的 controller 數(shù)量渲染層級(jí)不對(duì)displayList 順序顛倒Prompt 明確“底到頂”順序 人工審閱Git 沖突頻繁多人同時(shí)改同一 UI 包包級(jí)隔離禁止并行寫同一包文字內(nèi)容被 Agent 妄改需求描述不完整在協(xié)議里增加“支持原文引用”字段XML 語法正確但編輯器打不開版本不兼容或字段拼錯(cuò)先打開編輯器看報(bào)錯(cuò)日志再轉(zhuǎn)換器補(bǔ)兼容5. 給想接手這套流程的人四個(gè)實(shí)在建議前面把思路、代碼、坑都講完了最后說幾句掏心窩子的建議。如果你真想把 Agent 接進(jìn) FairyGUI 流程別急著一步到位按下面這個(gè)節(jié)奏來。5.1 從組件級(jí)接管開始別一上來就整面板我最開始想直接生成整個(gè)主界面結(jié)果被層級(jí)、控制器、關(guān)聯(lián)三座大山壓得喘不過氣。后來我退一步先讓 Agent 只生成“單組件”——比如一個(gè)按鈕、一個(gè)列表項(xiàng)、一個(gè)彈窗框架。這類結(jié)構(gòu)簡(jiǎn)單字段少校驗(yàn)規(guī)則也好寫。跑了幾天發(fā)現(xiàn)效率確實(shí)高再逐步擴(kuò)大到完整面板。步子太大容易扯著這點(diǎn)在 AI 流程里也一樣適用。5.2 建一個(gè)自己的組件模板庫Agent 生成的節(jié)點(diǎn)結(jié)構(gòu)雖然對(duì)但風(fēng)格不一定符合你們團(tuán)隊(duì)習(xí)慣。我的做法是把團(tuán)隊(duì)里既有的優(yōu)質(zhì)組件結(jié)構(gòu)抽成模板寫進(jìn)轉(zhuǎn)換器里。比如“標(biāo)準(zhǔn)按鈕”就是“底圖 文字 state 控制器”轉(zhuǎn)換器遇到type: button時(shí)直接用模板生成而不是讓 Agent 自由發(fā)揮。模板庫越厚Agent 的自由度就應(yīng)越小整體質(zhì)量越可控。5.3 用失敗案例反向喂給 Prompt每次 Agent 生成的組件被打回我都會(huì)把錯(cuò)誤原因整理成一句話加進(jìn) Prompt。比如“列表項(xiàng)內(nèi)部禁止嵌套滾動(dòng)容器”“所有文本節(jié)點(diǎn)必須提供 color”。實(shí)踐兩三個(gè)星期后Agent 的生成質(zhì)量會(huì)有肉眼可見的提升。這比換更大參數(shù)的模型管用因?yàn)閱栴}往往出在領(lǐng)域細(xì)節(jié)而不是模型智力上。5.4 留一條手工兜底的快捷通道最后提醒一句別把手工能力丟掉。我做這套流程時(shí)仍然保留了“手動(dòng)微調(diào)”的工作習(xí)慣——Agent 生成的組件進(jìn)編輯器后我會(huì)快速拖一兩個(gè)節(jié)點(diǎn)做微調(diào)。不是因?yàn)?Agent 不好用而是因?yàn)橛行┘?xì)節(jié)比如像素級(jí)對(duì)齊的視覺感受機(jī)器判斷不如人眼敏感。工具的意義是讓你把時(shí)間花在真正需要判斷力的事情上而不是幫你徹底偷懶。我現(xiàn)在的工作習(xí)慣已經(jīng)完全變了早上到公司先看設(shè)計(jì)稿更新把需求丟給 Agent它生成結(jié)構(gòu)、自動(dòng)校驗(yàn)、發(fā)布資源我這邊做審閱和微調(diào)。原來一天手拼兩三個(gè)面板的工作量現(xiàn)在能從容地做完一整層 UI 體系。這個(gè)方向未來還有很大空間比如把動(dòng)效、狀態(tài)機(jī)的生成也納入進(jìn)來但那又是另一篇文章了。