Agent preset
dsh-ugui-preset
UGUI制作模式:让 AI agent 在浏览器设计/预览 uGUI,并一键构建工程内可交互、自带测试数据的 uGUI prefab(DSH agent preset)
- Source
- BaronCyrus
- stars
- 4 stars
- License
- MIT
- Updated
- Updated 9 days ago
Readme
# UGUI制作模式(DSH Agent Preset)
让 AI agent 以任意美术合成 PSD 为起点,在浏览器里生成、校对和批准平台中立 UI Spec,模拟运行时状态与交互,再显式构建等价的 Unity Production/Preview Prefab。v2.0 稳定版的定位是**视觉驱动、人工批准、可移交的 uGUI 生产工作台**:生产交付与原型 Controller/mock 数据严格分离。
## 实机演示
过程:agent 产出 DSL → 浏览器模拟交互 → 显式构建 Unity Prefab(演示录制于早期版本;v2.0.0 的生产/Preview 双产物、语义锚点与视觉基准所有权规则以本文为准)。
https://github.com/user-attachments/assets/fae23504-ad3e-40ac-ab31-3ef53a69478b
## 功能
- **多画布设计器与稳定身份**:浏览器内可视化编辑 uGUI DSL(多 Canvas Workspace、稳定 nodeId、结构化验收),可先用 PascalCase 名称新建独立空白画布再导入新 PSD,并以 `expectedVersion` 保护删除不再需要的 Workspace Canvas。既有 Canvas 的新节点必须省略 nodeId 交给 Host 分配;Host 会拒绝未知显式 ID以及把旧 ID 改绑到另一语义节点的整体替换,防止历史消息、runtime/component 引用和 Unity ownership 静默漂移;升级前已有的纯英文 legacy 根身份保持兼容。
- **版本化 UI Spec 与校对闸门**:每次变更都会形成 `uiSpecVersion: 2` 历史快照并使旧批准失效;「校对」页集中处理可视化决策、记录 `once|screen|project|global` 作用域并支持历史恢复。只有 `review.status=approved` 且 `approvedVersion` 等于当前 Canvas 版本时才能构建。
- **领域无关的新界面契约**:非 PSD 新界面在首次写入前同时声明功能轮廓与视觉规格,把实体数量/导航、集合与主从详情、只读/可变操作、状态和交互逐项标记为已确认或假设;会改变层级与绑定的假设最多合并成一个范围问题。多区域、多状态或大量重复内容先写骨架和交互所有者、验收后再按稳定 nodeId 分区 patch,避免一次性整体重建。
- **项目/全局记忆**:模式长期规则保存在 preset 的 `docs/MEMORY.md`/`memory/tool-registry.json`;项目决策、交付记录与工具哈希保存在目标工程 `ProjectSettings/UGUIMaker/project-memory.json`。最新 UI Spec 与版本历史写入 `Assets/GeneratedUI/<Name>/Source`,不把 PSD 二进制提交进工程。
- **Agent 分析式 PSD 导入**:程序解析图层、把可安全映射的文字转换为 `TMP_Text`、按可配置的末尾标记(默认“原图”)在整份 PSD 中全局查找素材源并暂存 PNG,再产出带 `psdSource` 的初始草稿;标记查找不受 Group 限制。未配对但有像素的素材源会去掉标记后作为独立 runtime state candidate 导入,不再静默丢失;无可用像素者会进入明确 ignored 统计。隐藏的非素材组和叶子同样是潜在运行时状态,必须保留其初始显隐和语义候选信息。明显的底图/图标 + 可编辑文字会先组成紧边界非渲染父容器,由父节点统一承担移动、锚点、显隐、交互和整体动画,Image/TMP 叶子仍可独立编辑;随后 UGUI Agent 按运行时职责、动画边界、状态、重复项与交互控件生成可维护 DSL;导入器统一生成的 `topLeft` 只作为精确保像素的暂存坐标,完成态会把满铺内容、大面积内嵌区域和固定节点分别转换为 `stretch`、边缘或中心语义锚点,当前绝对像素保持不变。「校对」页的“整理语义锚点”可对既有 Canvas 执行相同的版本化迁移,并通过逐节点 frame round-trip 防止漂移;到两个响应位置等距的节点不会静默猜测,而是生成一次性人工决策。UI Spec 阶段同时把 `node.name` 统一为同级唯一的语义英文 PascalCase;原始美术层名只保存在 `psdSource`,因此 Web 层级与 Unity GameObject 名始终一致且可追溯。「校对」页也可对既有 Canvas 执行版本化的“整理整体层级”:除普通 Image/TMP 组合外,位于 Button 范围内却被按图层类型拆走的文字会归入对应 Button,使移入动画、相对锚点和整体显隐由同一控件所有;当控件拥有满铺的实际背景 Image 时,内容边距容器会成为该 Image 的后代,以背景 RectTransform 而不是同级几何巧合作为坐标基准,Button/Toggle 仍留在外层语义控件。未引用的 inferred 纯透传包装会安全清理;runtime/review 引用、Layout 职责或绘制顺序使移动不安全时转为人工决策。同一语义锚点诊断也覆盖非 PSD Canvas:LayoutGroup 控制的子节点不产生噪声,高置信几何错误和自由定位交互控件的错误边缘所有权会阻止交付,其他可疑固定锚点作为 warning 供 Agent 检查。所有幸存节点保持绝对像素和 nodeId,扁平 graphic 绘制顺序保持不变。
- **PPU Profile 与安全文字**:通用 PSD Profile 默认 `Canvas.referencePixelsPerUnit=100`、`Sprite.pixelsPerUnit=100`;项目可在嵌套 `psdImport.ppuProfile` 中配置为 `100/25` 等组合。该配置是项目唯一权威值,浏览器会显示并锁定它;单次请求或既有 DSL 漂移时会在写 Assets 前拒绝。普通文字安全转换为 TMP;可通过每屏 Export Profile 的 `fontAssetPath` 明确指定 Unity TMP_FontAsset,省略时使用项目 TMP Settings 默认字体;无法可靠还原的文字才栅格化。浏览器字体只在 Canvas 暂存,上传时会修复常见的短 OS/2 v5 表以兼容 Chromium OTS,不修改工程源字体;字体按实际承载设计器/预览器的 popup Document 附着并以 Document 为缓存作用域,关闭重开窗口会重新注册。目标栏持续显示“加载中/已加载/加载失败”徽章,失败时明确回退系统字体并可重试。Host 视觉验收只把文件存在、格式/哈希正确及全部导入 TMP 引用一致记为素材就绪,不把 `previewFont*` 元数据冒充浏览器已应用;浏览器徽章与 Unity TMP/最终截图仍是彼此独立的验收层。视觉验收会对 PSD 单行 TMP 的临界宽高给出换行/溢出警告,最终仍需核对 Unity 截图。
- **图片渲染契约**:`Image.imageType` 支持 `simple|sliced|tiled|filled`;`spriteBorder` 使用原图像素 `[left,bottom,right,top]`,`fillCenter` 控制中心区域;Filled Image 共享 `fillAmount/fillMethod/fillOrigin/fillClockwise` 语义,Web 模拟与 Unity `Image.Type.Filled` 使用同一 UI Spec;Unity Sprite 固定使用 Point、无压缩、无 Mipmap、sRGB/Alpha、Full Rect 导入设置。
- **命名状态与跨平台交互**:DSL 顶层 `runtime.stateGroups` / `runtime.interactions` 表达状态族和声明式机械交互;动作支持 `setState|cycleState|setActive|setText|addNumber|setFill|emit`,`cycleState.textTargets` 可让角色切换同时更新多块文字。设计器支持查看当前/全部状态,预览器支持运行模拟、选中子树和全屏预览,事件日志默认折叠并仅在用户主动展开后显示;Unity 生成代码以相同顺序执行同一动作。
- **分析进度可见**:UGUI 窗口持续显示“排队 → 读取 → 规划 → 写入 → 验收 → 完成”的进度;摘要只呈现可操作的高层决策,不暴露模型隐藏思维链。
- **显式双产物与 Demo Scene**:PSD 导入始终只暂存;每屏 Export Profile 默认输出到 `Assets/GeneratedUI/<Name>/{Prefabs,Runtime,Preview,Sprites,Source,Demo}`。每次构建必须提供已批准的当前 `expectedVersion`,并在脚本/图片写入前通过 workbench、Manifest、binding、输出 ownership 与配置预检。生产 `<Name>.prefab` 只挂载生成的 `<Name>View`;`<Name>.Preview.prefab` 才增加临时 `<Name>PreviewController`/`<Name>PreviewMock`,并生成 `<Name>.Demo.unity`。Preview 源自动加 `#if UNITY_EDITOR`,项目 Agent 后续可替换业务逻辑而无需改变视觉 Prefab 层级。
- **所有权与冲突契约**:所有权 Manifest 与三方冲突策略只更新生成器拥有的内容,保留用户节点、用户组件和 UnityEvents,冲突时明确报错而非静默覆盖。Preview/Production 节点优先按 persistent local ID 和原始 sibling-index hierarchy 映射,重复同级名称不会再造成歧义。缺少或不匹配 Manifest 时一律拒绝接管,当前不暴露可由模型自行设置的采用开关。
- **完整输入事务与可观测性**:生成脚本、PNG 与对应 `.meta` 共同进入可逆事务;Worker 未提交时按并发修改保护逆序恢复,dirty Worker 事务则明确返回 retained 状态。构建结果统一包含结构化 `code/details/classification/mutation`,以及 Host 模块 revision、生效配置、配置加载时间和磁盘漂移检测;发现旧实例时在写入前返回 `reload-required`。
- **显式两阶段 PSD 制作**:pending-agent 阶段只允许保持导入视觉叶子并完成运行时结构分析;验收完成后才进入普通 DSL 业务增强,可新增选中态、文字颜色副本和透明点击层。若跨阶段修改,错误会直接返回下一阶段操作提示。
- **逻辑同步闸门**:`logic.js` 领先 `view.cs` 时浏览器显示“逻辑同步中”,当前 Agent 完成语义核对后继续原构建,界面徽章持续显示进度。
## 环境要求
- DSH(DeepSeek Harness)Web 部署
- Node.js 20+ 与 pnpm 10.28.2(插件依赖使用已提交的 frozen lockfile 安装)
- 一个运行中的 Unity 工程(已用 Unity Editor 打开;当前语义缓存钉住 uGUI 2.0.0 / Unity 6000.3,其他版本按文档过期流程重核即可)
- Unity 官方 CLI(`unity` 在 PATH 上)
- **macOS / Linux / Windows 均支持**(macOS/Linux 走 bash 入口;Windows 自动切换到 `unity-cli.py` Python 入口,需要 Python 3;无需 bash/jq)
## 安装
```bash
# 1. 克隆到 DSH preset 目录(DSH 按目录发现 preset)
git clone https://github.com/BaronCyrus/dsh-ugui-preset.git ~/.dsh/.agent-presets/ugui
# Windows PowerShell: git clone ... "$env:USERPROFILE\.dsh\.agent-presets\ugui"
# 2. 注册浏览器端插件包(跨平台,幂等)
node ~/.dsh/.agent-presets/ugui/setup/install.mjs
# 3. 配置目标 Unity 工程
cd ~/.dsh/.agent-presets/ugui
cp setup/ugui.config.example.json ugui.config.json
# 编辑 ugui.config.json:projectPath 必填;asmdef 工程需把 assemblyName 改成对应程序集名
# productionPrefabDir/scriptDir 配 Production;previewPrefabDir 留在 Editor,previewScriptDir 必须在非 Editor 的可挂载程序集目录
# 无 asmdef 时 previewAssemblyName 使用 Assembly-CSharp;有 asmdef 时填写其名称且不得是纯 Editor-only/排除 Editor 的程序集
# Host 会自动给 view/testdata 源加 #if UNITY_EDITOR,Preview Prefab 仍不会进入 Player
# psdImport.sourceLayerMarker 配置素材源末尾标记;psdImport.ppuProfile 配置 Canvas/Sprite PPU
# 通用默认值为 100/100;若项目采用放大素材工作流可配置为 100/25
# defaultPsdTextMode 控制文字默认导入为 editable TMP_Text 或 raster Image
# PSD 导入的 TMP_Text 使用项目 TMP Settings 默认字体;浏览器 TTF/OTF 仅暂存到工作区
```
从 v2.0.2 升级到 v2.0.3 时,拉取代码后必须重启 DSH 并刷新现有 Web 页面;本版本把 PSD 预览字体附着到实际承载设计器/预览器的 popup Document,升级素材验收协议到 v8,并增加浏览器/Host 协议漂移保护。已有 Web Profile link 不变,无需重新安装;若从更早版本跨级升级,仍按下述 v2.0.2 步骤执行安装脚本。
从 v2.0.0 或 v2.0.1 升级到 v2.0.2 时,请在拉取新代码后重新执行一次 `node ~/.dsh/.agent-presets/ugui/setup/install.mjs`。DSH 0.1.2 起不再从 preset 直接子树发现浏览器 bundle,安装脚本会把 host-noop Client 发现行补入 Web Profile;v2.0.2 同时让入口显隐读取可变的 `agentPreset` Session projection,而不是会在空会话切换模式后保留旧值的不可变 Header。随后必须重启 DSH 并刷新页面。
从 v1.2.0 或更早版本升级时,旧的 `Assets/Editor/DshUguiPreview/Generated` / `Assembly-CSharp-Editor` 配置会被明确拒绝,因为其中的 MonoBehaviour 在 Unity 6 无法可靠挂载。请先备份工程,将整个生成脚本目录连同每个 `.meta` 迁移到非 Editor 目录(默认 `Assets/DshUguiPreview/Generated`)并改用运行时兼容程序集;保留 `.meta` 才能维持 Preview Prefab 的脚本 GUID。首次安全构建会只识别这一精确旧目录格式,自动把 generated-script ownership sidecar 路径迁到当前配置,并通过 C/B/D 规则给仍等于旧 baseline 的源添加 `UNITY_EDITOR` guard;任何自定义旧路径或内容分歧仍会阻塞而不猜测。完成文件/配置迁移后必须重启 DSH,当前 Host 实例不会热替换。
重启 DSH 并刷新现有 Web 页面后,可在 `plugins/dsh-ugui-tools/` 运行 `npm run test:runtime-psd`,确认当前 `127.0.0.1:3080` 已启用语义分析协议 v8、预览资源验收和进度路由;随后新建「UGUI制作模式」会话即可开始使用。可提前让 Agent 调用一次 `ugui_setup`,也可以直接首次构建:Host 会在预检发现 UIDslWorkbench 缺失时自动创建并继续同一次请求。
## 使用
1. 会话中描述界面需求 → Agent 产出 DSL 并在浏览器设计器/预览器中呈现;有新的 PSD 且不想覆盖现有内容时,先在 Canvas 标签栏点击「+ 新建」,填写唯一 UI 类名与参考分辨率,再点击「导入 PSD」。预览字体只暂存到工作区,设计器/预览器目标栏会显示当前 popup Document 的字体加载状态;“已加载”才表示浏览器当前窗口已附着该字体,“加载失败”会明确回退并可重试。Unity 的 `TMP_Text` 仍使用项目 TMP Settings 默认字体。导入只替换当前 Canvas 为暂存草稿并提交 Agent 分析,不自动生成 Prefab。标签栏「删除」会用当前 `expectedVersion` 删除该 Workspace Canvas 及本地草稿,但为保护 Unity 引用,不会自动删除 Production/Preview Prefab、生成脚本或已导入图片。
2. PSD 中可见效果层负责布局;名称以 `psdImport.sourceLayerMarker`(默认“原图”)结尾的素材层在整份 PSD 中全局参与配对,与效果层是否同组无关。配对素材保持自身像素尺寸;未配对但有像素的素材层会去掉末尾标记、按 Canvas/Sprite PPU 比例形成独立 runtime state candidate,初始 hidden 状态会保留;无像素者会进入 ignored 统计并给出原因。隐藏的普通 Group/叶子同样作为运行时状态候选保留,不得因初始不可见而删除或强制激活。普通文字安全转换为 TMP;无法可靠还原的特殊文字才回退为 `Image`。隐私边界:PSD 文件名、图层名称和文字元数据会发送给当前 Agent/模型;所选 TTF/OTF 二进制只保留在本机工作区。
3. Agent 可在顶层 `runtime.stateGroups` / `runtime.interactions` 中声明状态与机械交互。设计器切换“当前状态/全部状态”检查结构,预览器执行状态矩阵、按钮事件、数值和 Fill 模拟;业务数据仍属于项目或可选 Preview。
4. 在「校对」页处理未决项并由人类批准当前版本。任一 DSL、Profile 或决定变更都会自动撤销旧批准;未批准版本的「生成 Prefab」保持禁用。
5. 显式点击「生成 Prefab」(或调用带当前 `expectedVersion` 的 `ugui_build`)后才导入暂存素材。默认生成 `<Name>.prefab`、可交互 `<Name>.Preview.prefab`、`<Name>.Demo.unity` 与带 `[SerializeField] private` 引用的 `<Name>View.cs`;Worker 保存 Prefab 后逐项回读绑定,Production 不引用 Preview Controller/mock。
6. 更新既有 Prefab 遵循所有权 Manifest/三方冲突合同:用户节点、组件与 UnityEvents 不应被静默覆盖;冲突需处理后重试。没有有效 Manifest 的旧资产当前一律拒绝接管;必须先通过受信任的项目迁移/备份流程建立基线,不能靠删除 `TestData.cs` 作为移交步骤。
## 目录结构
```
├── preset.yml / agent.cordis.yml # preset 元数据与组合(persona、工具行)
├── ugui.config.json # 你的工程配置(不入库;参考 setup/ugui.config.example.json)
├── docs/ # 开发合同与跨项目长期记忆
├── memory/tool-registry.json # 持久 Unity Worker/CLI 工具注册表与版本
├── plugins/dsh-ugui-tools/ # 主插件:host 工具/路由 + 浏览器设计器/预览器
├── plugins/dsh-ugui-entry-guard/ # 入口守卫(web profile 常驻):入口按钮缺失时自动刷新一次页面
│ ├── lib/ # host.js(工具与构建管线)/ client.js(设计器与预览器)
│ ├── unity/BuildUiWorker.cs # Unity 侧构建 worker(经 unity-cli 任务在工程内执行)
│ ├── test/ # 行为测试(npm test)
│ ├── COMPONENTS.md # DSL 组件契约
│ └── UNITY_SEMANTICS.md # uGUI 交互语义本地缓存(按组件分节,含版本钉)
├── vendor/unity-cli/ # 内嵌的 Unity Editor 控制通道(bash 入口 + Windows 用 Python 移植入口)
├── setup/install.mjs # Web Profile link 与 Client bundle 发现行注册
├── setup/ugui.config.example.json # 工程配置样例
└── fixtures/canvases/ # 示例画布(测试背包:DSL + 逻辑 + 视图脚本三件套)
```
## 开发
```bash
cd plugins/dsh-ugui-tools && npm test
```
注意:`ugui.config.json` 存在且指向真实工程时,语义缓存新鲜度测试会对该工程生效。
- `host.js`、`ugui.config.json`、`agent.cordis.yml`:不会通过浏览器 HMR 替换当前 Host 实例;修改 Host 时还需递增 host 行 `?v=`,然后重启 DSH。构建会比较磁盘 revision 与启动快照,发现漂移即返回 `reload-required`,不会继续用旧配置写工程。
- `client.js`:递增插件 package 版本;只有从 DSH checkout 运行 `pnpm run dev:web` 重建 bundle 时,现有页面的 Client HMR receiver 才能自动加载。其他情况请重启 DSH 并刷新现有 `127.0.0.1:3080` 页面;启动另一个 Vite server 不会替换该 GUI。
- 可调用 `ugui_impl_probe` 查看 `hostModuleRevision`、`configLoadedAt` 与当前生效的 Preview/PPU 配置,避免根据磁盘文件猜测运行实例。
架构与生命周期约定见 [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)。
## 商业支持
本 preset 以 MIT 协议免费开放全部功能(含商用)。如果你的团队需要以下服务,欢迎联系洽谈:
- **接入支持**:在你的 DSH + Unity 工程里完成部署、调通首块画布
- **定制开发**:新 DSL 组件、私有交互语义、内部管线对接
- **培训咨询**:uGUI 生产流程与 agent 协作模式落地
联系方式:378905096@qq.com / 微信 codiee_zhang(或 GitHub [@BaronCyrus](https://github.com/BaronCyrus) 私信/Issue)。
社区支持通过 GitHub Issues 进行(尽力而为,不保证时效)。
## 许可
[MIT](LICENSE) © 2026 BaronCyrus。本仓库全部内容(含 `vendor/unity-cli`)均为原创并以同一协议发布。
Install
# Copy the composition to $DSH_HOME/.agent-presets/dsh-ugui-preset/agent.cordis.yml
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install baroncyrus-dsh-ugui-preset from the hub