diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..85f9cd9 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,50 @@ +name: Deploy GitHub Pages + +on: + push: + branches: + - copilot/website + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: github-pages + cancel-in-progress: true + +jobs: + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Configure Pages + uses: actions/configure-pages@v5 + + - name: Prepare static site + run: | + mkdir _site + rsync -a --delete \ + --exclude '.git' \ + --exclude '.github' \ + --exclude '.Doxyfile' \ + --exclude '.gitignore' \ + --exclude '_site' \ + ./ _site/ + touch _site/.nojekyll + + - name: Upload static site + uses: actions/upload-pages-artifact@v3 + with: + path: _site + + - name: Deploy + id: deployment + uses: actions/deploy-pages@v5 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/Document/AnimationMcpProtocol.md b/Document/AnimationMcpProtocol.md new file mode 100644 index 0000000..101c3f3 --- /dev/null +++ b/Document/AnimationMcpProtocol.md @@ -0,0 +1,125 @@ +# Animation MCP Protocol Draft + +本文记录当前开源 Sequencer/UMG Animation MCP 的精简协议原则。范围限定为 UE 5.8;不引入商业版服务依赖。 + +## 设计原则 + +1. Target 是默认操作对象。`set_target_umg_asset` 决定 UMG 资产;`set_animation_scope` 决定当前动画;`set_widget_scope` 决定当前动画内的控件。下层 Target 继承上层 Target。 +2. 读操作返回语义。读动画时默认返回概览;读控件时返回该控件被动画驱动的属性时间线;读时间时返回该时刻的属性值。只有调试兼容层才返回完整 keyframe dump。 +3. 写操作只做并集覆盖和追加。`animation_append_widget_tracks` 和 `animation_append_time_slice` 只能覆盖已有关键帧或追加新关键帧,不允许隐式删除。 +4. 删除必须走单独命令。删除指定控件、属性、时间的 key 使用 `animation_delete_widget_keys(confirm_delete=true)`;删除整段动画使用 `delete_animation(confirm_delete=true)`。 +5. 所有默认 MCP 返回都必须包含可复述的计数或上下文,例如动画名、控件名、轨道数、关键帧数、时间点或删除数量。 + +## 当前精简工具 + +| Tool | 作用 | +| --- | --- | +| `set_animation_scope(animation_name)` | 设置当前动画 Target;若动画不存在则自动创建。 | +| `set_widget_scope(widget_name)` | 设置当前动画内的控件 Target。 | +| `get_all_animations()` | 返回当前 UMG Target 的动画简表。 | +| `animation_overview(animation_name?, widget_name?, property_name?)` | 返回紧凑概览:被动画驱动的控件、属性、关键时间点、轨道数和关键帧数。 | +| `animation_widget_properties(animation_name?, widget_name?, property_name?)` | 按控件视角读取属性时间线,只返回被动画驱动的属性。 | +| `animation_time_properties(times, animation_name?, widget_name?, property_name?)` | 按一个或多个时间点读取属性值。 | +| `create_animation(animation_name)` | 创建或聚焦动画。 | +| `delete_animation(animation_name, confirm_delete=true)` | 显式删除整段动画。 | +| `animation_append_widget_tracks(widget_name, tracks, animation_name?)` | 控件视角追加/覆盖多个属性轨道的关键帧。 | +| `animation_append_time_slice(time, widgets, animation_name?)` | 时间视角追加/覆盖一个时刻下多个控件的属性值,推荐只提供 diff。 | +| `animation_delete_widget_keys(property_name, times, widget_name?, animation_name?, confirm_delete=true)` | 显式删除指定控件、属性、时间点的关键帧。 | + +## 默认缺省 + +最短可用流程: + +```python +set_target_umg_asset("/Game/UI/W_Login") +create_animation("Intro") +set_animation_scope("Intro") +set_widget_scope("LoginCard") +animation_append_widget_tracks( + widget_name="LoginCard", + tracks=[ + {"property": "RenderOpacity", "keys": [{"time": 0.0, "value": 0.0}, {"time": 0.4, "value": 1.0}]}, + {"property": "RenderTransform.Scale", "keys": [{"time": 0.0, "value": {"x": 0.95, "y": 0.95}}, {"time": 0.4, "value": {"x": 1.0, "y": 1.0}}]}, + ], +) +animation_overview() +``` + +`animation_name` 和 `widget_name` 可以显式传入,也可以从当前 Target 推导。需要精确操作时传参;需要流式编辑时使用 Target。 + +## 读语义层级 + +- `get_all_animations`:图书馆目录,回答有哪些动画。 +- `animation_overview`:读一本书的目录,回答有哪些控件、属性和关键时间。 +- `animation_widget_properties`:读一个控件章节,回答该控件哪些属性在何时变化。 +- `animation_time_properties`:读一个时间页,回答该时刻哪些属性值成立。 + +`get_animation_keyframes`、`get_animated_widgets`、`get_animation_full_data`、`get_widget_animation_data` 保留在后端兼容层,用于调试或旧脚本迁移,不进入默认 MCP 提示面。 + +## 写与删除 + +`animation_append_widget_tracks`: + +```json +{ + "widget_name": "LoginCard", + "tracks": [ + { + "property": "RenderTransform.Translation", + "keys": [ + {"time": 0.0, "value": {"x": 0, "y": 24}}, + {"time": 0.5, "value": {"x": 0, "y": 0}} + ] + } + ] +} +``` + +`animation_append_time_slice`: + +```json +{ + "time": 0.75, + "widgets": [ + { + "widget_name": "LoginCard", + "properties": { + "RenderOpacity": 1.0, + "RenderTransform.Angle": 2.0 + } + } + ] +} +``` + +删除必须显式: + +```json +{ + "property_name": "RenderTransform.Scale.X", + "times": [0.5], + "widget_name": "LoginCard", + "confirm_delete": true +} +``` + +不带 `confirm_delete=true` 的删除请求必须失败,并返回可解释的安全提示。 + +## 隐藏兼容命令 + +以下命令仍在后端路由中保留,但默认 MCP prompt 不暴露: + +- `get_animation_keyframes` +- `get_animated_widgets` +- `get_animation_full_data` +- `get_widget_animation_data` +- `set_property_keys` +- `set_animation_data` +- `remove_property_track` +- `remove_keys` + +这些命令只能作为内部兼容或调试工具;新 Skill 和 Demo 应使用精简工具。 + +## ToolMode 支撑工具 + +Animation ToolMode 除了上述动画工具,还必须允许 `set_target_umg_asset`、`get_target_umg_asset`、`set_target_widget`、`get_target_widget` 和 `save_asset`。这些不是动画语义本身,但它们是 Target/缺省链路和保存流程的一部分。 diff --git a/Document/BlueprintBluecodeProtocol.md b/Document/BlueprintBluecodeProtocol.md new file mode 100644 index 0000000..df3b85b --- /dev/null +++ b/Document/BlueprintBluecodeProtocol.md @@ -0,0 +1,192 @@ +# Blueprint Bluecode Protocol Draft + +本文记录新的 Blueprint MCP 方向。范围限定为 UE 5.8;当前实现仍是过渡期节点级 MCP,bluecode 尚未落地。 + +## 为什么需要 bluecode + +旧 Blueprint MCP 的主要问题: + +1. 需要频繁逐节点调用 MCP,交互成本高。 +2. `get_function_nodes` 返回节点 ID、类名等调试信息,但缺少执行语义、参数语义和数据依赖压缩。 +3. `add_step`/`prepare_value`/`connect_data_to_pin` 把 AI 暴露在节点和 pin 细节里,信息密度低。 +4. 旧 `delete_node`、`delete_variable` 是直接删除命令,不符合 Issue 15 的删除困难原则;默认 MCP 应隐藏它们,直到删除协议改为显式 `confirm_delete=true`。 + +bluecode 的目标不是一次替换所有后端,而是像 HLSL 替代 Material 图编辑一样,先定义高层协议,再逐步迁移。 + +## Target 层级 + +Target 继承关系: + +1. `set_target_umg_asset`:当前 UMG/Widget Blueprint 资产。 +2. `set_target_widget`:当前控件,可用于优先匹配 `Widget.Event` 或绑定函数。 +3. `bluecode_set_function`:当前函数、事件或图。 + +`bluecode_set_function` 的目标格式建议: + +```text +FunctionName +WidgetName.EventName +/Game/UI/W_Login:EventGraph +/Game/UI/W_Login:LoginButton.OnClicked +``` + +缺省规则: + +- 未给资产路径时使用 Active UMG Target。 +- 存在 Widget Target 时,优先匹配该控件的事件或绑定函数。 +- 匹配多个候选时必须失败,并返回候选列表。 +- 设置函数后,逻辑入口称为 `main`,空结束称为 `end`,返回称为 `return`,分支块使用稳定标签。 + +## 读语义 + +建议工具: + +| Tool | 作用 | +| --- | --- | +| `bluecode_read_function(detail?)` | 以代码式摘要读取当前函数。默认返回执行流和必要数据依赖;`detail="debug"` 时才返回节点 ID 和 pin。 | +| `bluecode_read_variables()` | 读取变量、类型、默认值和引用摘要。 | +| `bluecode_read_events()` | 读取当前 UMG Target 下可编辑事件和已绑定事件。 | + +默认 `bluecode_read_function` 应输出类似: + +```text +main() + PrintString("Welcome") + if IsValid(LoginButton): + SetVisibility(LoginPanel, Visible) + end +``` + +返回 JSON 同时带结构化信息: + +```json +{ + "function": "LoginButton.OnClicked", + "entry": "main", + "exit": "end", + "code": "main()\n PrintString(\"Welcome\")\n end", + "exec_paths": 1, + "data_dependencies": [ + {"name": "LoginPanel", "kind": "widget_reference"} + ], + "debug_nodes_available": true +} +``` + +## 写语义 + +建议工具: + +| Tool | 作用 | +| --- | --- | +| `bluecode_apply(code, anchor?, mode?)` | 并集式应用代码片段。默认插入到当前函数 `end` 前。 | +| `bluecode_apply_variables(variables)` | 并集式添加/更新变量,不删除未提及变量。 | +| `bluecode_connect(connects)` | 处理少量显式数据依赖或 pin 连接,作为 escape hatch。 | +| `bluecode_compile()` | 编译当前 Blueprint,返回紧凑诊断。 | + +写入原则: + +- 写操作只能追加或覆盖匹配到的节点、变量、连接。 +- 如果输入片段省略了既有节点,不视为删除。 +- 如果片段与既有节点相似,应按匹配策略复用或在右侧插入,并返回 `merge_report`。 +- 无法连接的数据节点应先尝试转换为参数表达式,再尝试 cast,仍失败时放入 `floating_nodes`,并在返回中解释。 + +匹配优先级建议: + +1. 明确 node id 或 stable label。 +2. 函数名、成员类、目标对象和参数完全一致。 +3. 函数名和关键参数一致。 +4. 节点类型一致且邻接节点相似。 +5. 无法确认时追加新节点,不覆盖旧节点。 + +示例: + +已有: + +```text +main() + PrintString("one") + PrintString("three") + end +``` + +输入: + +```text +PrintString("two") +``` + +结果: + +```text +main() + PrintString("one") + PrintString("three") + PrintString("two") + end +``` + +如果输入: + +```text +main() + PrintString("two") + PrintString("three") + end +``` + +结果: + +```text +main() + PrintString("one") + PrintString("two") + PrintString("three") + end +``` + +`PrintString("three")` 被匹配为既有节点,`PrintString("two")` 插入到它左侧。 + +## 删除语义 + +建议工具: + +| Tool | 作用 | +| --- | --- | +| `bluecode_delete(targets, confirm_delete=true)` | 删除节点、变量或连接。必须显式确认。 | + +删除必须满足: + +- 未传 `confirm_delete=true` 时失败。 +- target 必须是稳定 ID、稳定 label、变量名或连接描述。 +- 匹配多个对象时失败,并返回候选。 +- 删除返回 `deleted_count`、`affected_edges` 和 `new_flow_summary`。 + +## 当前过渡工具 + +当前默认 Blueprint MCP 只保留: + +- `set_edit_function` +- `add_step` +- `prepare_value` +- `connect_data_to_pin` +- `add_variable` +- `get_variables` +- `get_function_nodes` +- `set_cursor_node` +- `search_function_library` +- `compile_blueprint` + +隐藏兼容命令: + +- `delete_node` +- `delete_variable` + +这些删除命令后端仍存在,但默认 MCP prompt 和 Blueprint ToolMode 不暴露。它们需要在后续实现 `confirm_delete=true` 后再重新评估。 + +## 下一步实现建议 + +1. 先实现 `bluecode_read_function`,把当前节点图压缩成代码式摘要。 +2. 再实现 `bluecode_apply`,内部可复用现有 `add_step`、`prepare_value`、`connect_data_to_pin`。 +3. 最后实现 `bluecode_delete`,替代旧节点级删除。 +4. 保留旧节点工具作为 backend compatibility,逐步从默认 prompts 中移除。 diff --git a/Document/ChatMessage_Lifecycle.md b/Document/ChatMessage_Lifecycle.md new file mode 100644 index 0000000..134a77f --- /dev/null +++ b/Document/ChatMessage_Lifecycle.md @@ -0,0 +1,43 @@ +# ChatMessage 生命周期(前端展示视角) + +## 目标 +本文只描述前端消息展示中的“当前活跃 ChatMessage”模型,不混入窗口架构、目录分层或总流程节点。 + +## 核心概念 +- 后端负责产生状态变化,前端只负责订阅、渲染和事件转发。 +- ChatMessage 是“活着的消息”状态机:它可以在流式输出期间持续增量更新。 +- `ChatList` 只是滚动容器和历史承载面,不是消息概念本体。 +- `StartNewChatMessage` 的语义不是“创建一个固定死的对象”,而是“结束当前活跃消息并开始下一条消息”。 +- 如果当前没有活跃消息,调用 `StartNewChatMessage` 应当是无操作。 + +## 生命周期规则 +1. 新消息开始时,系统进入一个新的活跃 ChatMessage。 +2. 流式内容、状态、错误、完成态都更新到当前活跃消息。 +3. 当后端明确切换到下一条消息时,前端收到 `StartNewChatMessage` 信号。 +4. 如果已有活跃消息,则将其归档为只读历史,并标记为 complete。 +5. 归档后的历史消息不应再被当作当前可编辑对象直接访问。 +6. 新消息到来后,再建立新的活跃消息承载后续内容。 + +## 消息类型 +- 用户消息:由输入框触发,进入历史展示。 +- Agent 消息:由后端响应流驱动,通常是活跃状态的主要承载对象。 +- Task 消息:由 TaskSubsystem 事件触发,作为单独的 UI 节点展示,不与普通 assistant turn 混用。 +- MCP 消息:由工具执行/审批回调触发,按请求序列展示,并在审查点展开详细信息。 + +## 与前端交互的约束 +- 前端只接收后端事件,不主动推进业务流。 +- 所有按钮、重试、审批、展开、复制、打开目标等操作都只通知后端。 +- 前端可以维护当前活跃消息的 UI 状态,但历史消息一旦归档即只读。 +- 不同 agent 的消息切换,由后端在切换时触发 `StartNewChatMessage`,前端不自行推断。 + +## 与 ChatList 的关系 +- ChatList 是滚动容器和历史承载面,但它不负责决定后端业务流转。 +- ChatList 只维护当前活跃消息的 UI 状态和历史列表的渲染。 +- `StartNewChatMessage` 是少数显式暴露的边界信号,用来收束当前消息并准备下一条消息。 + +## 代码对应 +- `SUmgMcpChatList::StartNewChatMessage` +- `SUmgMcpChatList::SetConversationState` +- `TheChatMessageGroupDisplayInList::FinalizeAsHistory` +- `SUmgMcpChatWindow::ExecuteQuestionRequest` +- `SUmgMcpChatWindow::OnAIResponse` diff --git a/Document/ChatWindow_Architecture.md b/Document/ChatWindow_Architecture.md new file mode 100644 index 0000000..0e42f7f --- /dev/null +++ b/Document/ChatWindow_Architecture.md @@ -0,0 +1,176 @@ +# ChatWindow 架构树(概念边界图) + +## 目标 +本文只描述 ChatWindow 的概念树与边界,不再把“目录名”当成概念本身。 +`FabServer_SerialFlow.md` 是完整流程;本文件只负责说明哪些 UI 概念允许存在,哪些只是待审计实现细节。 + +## 总原则 +- UI 只做布局、显示、事件转发和订阅后端回调。 +- 后端 subsystem 负责业务状态、任务状态、回答归属和工具执行顺序。 +- 封装不是目的;只有一个概念不可再分时才保留一个函数或一个类。 +- 若某个名字不在流程文档和项目规则中形成独立概念,它就只是实现细节,不能被当作架构中心。 + +## 概念树 + +### 1. ChatWindow(窗口入口) +- 负责整体布局、显隐切换、按钮事件转发、订阅后端回调。 +- 允许存在的子概念: + - 顶部工具区 + - 中央消息显示区 + - 底部输入区 + - 会话切换 / 历史入口 + +### 1.1 全局架构图 (Global Architecture Boundaries) + +```mermaid +graph TD + %% Backend Subsystems (Out of UI) + subgraph Backend ["Backend Subsystems 层 (非 UI, 掌管状态与流转)"] + AMS["UUmgMcpActiveMessageSubsystem\n(管控当前进行中的对话与生命周期)"] + FCS["UUmgMcpFunctionCallSubsystem\n(解析与分发MCP卡片构建)"] + TS["UUmgMcpTaskSubsystem\n(管控Task挂起预设及接手回调)"] + AMS <--> FCS + AMS <--> TS + end + + %% UI Root + Root["SUmgMcpChatWindow\n(顶级 UI 容器)"] --> TopBar + Root --> Welcome + Root --> Hub + Root --> BottomBar + + Root -.-|监听状态更新| Backend + + %% TopBar Components + subgraph TopBarArea ["TopBar 区域 (Components)"] + TopBar["SUmgMcpChatTopBar"] --> Avatar["SUmgMcpAvatar (用户头像)"] + Avatar --> Config["SConfigByAuthentication\n(登录与模型配置选项)"] + end + + %% Initialization Page + subgraph WelcomeArea ["Welcome 区域 (Components)"] + Welcome["SUmgMcpChatWelcome\n(欢迎与历史选择)"] + end + + %% Message Interaction Hub (Strictly bounded Flow Sync) + subgraph MessageHub ["MessageInteractionHub 区域 (仅反映 Flow,不自己决策)"] + Hub["SUmgMcpMessageInteractionHub\n(主消息流面板)"] + Hub --> UserMsg["SUmgMcpUserMessageWidget\n(用户文本)"] + Hub --> AgentGroup["SUmgMcpAgentResponseGroup\n(AI 轮次组)"] + Hub --> TaskNode["SUmgMcpTaskBeginNode / SUmgMcpTaskEndNode\n(任务启停界碑)"] + AgentGroup --> ToolBlock["SUmgMcpToolExecutionBlock\n(审批执行卡片)"] + end + + %% BottomBar Components + subgraph BottomBarArea ["BottomBar 区域 (Components)"] + BottomBar["SUmgMcpChatInput\n(打字与模式输入框)"] --> Abilities["SUmgAbilitiesPanel\n(选中 Task 模式时的外挂面板)"] + end +``` + +### MessageInteractionHub 深度架构 + +```mermaid +graph TD + List["MessageInteractionHub (容器,与后端联动)"] --> UserMsg["UserMessageWidget (用户原件)"] + List --> AgentTurn["AgentResponseGroup (AI 响应轮次)"] + List --> TaskEntry["TaskInteractionNode (任务入口)"] + List --> SysHint["SystemNotificationWidget (系统提示/错误恢复)"] + + subgraph "AgentResponseGroup 内部组织细节" + AgentTurn --> Header["Header (头像与 Agent 标识)"] + AgentTurn --> Body["Body (内容流垂直容器)"] + Body --> TextMsg["ResponseText (AI 文字回复)"] + Body --> MCPReq["ToolExecutionBlock (工具请求卡片)"] + + %% ToolExecutionBlock 的内部结构 + MCPReq --> ItemList["Request List (待处理工具列表)"] + MCPReq --> RunBtn["Execute Button (用户执行/审批按钮)"] + end +``` + +### 2. MessageInteractionHub(消息交互枢纽) +> 这里是“消息窗口 / 总消息列表”的概念,强调与后端的联动,并且它仅仅是 `FabServer_SerialFlow` 的前端 UI 同步表面。 + +- 目录结构:`MessageInteractionHub/` 文件夹。 +- 核心职责:完全同步后端的 `UUmgMcpActiveMessageSubsystem` 和 `UUmgMcpFunctionCallSubsystem`,**严格根据状态流转的委派刷新自身界面**。任何脱离 Flow 文档说明的 UI 内部截留逻辑都要被删除。 +- 允许存在的组件级子概念(它们都从属于 MessageInteractionHub 文件夹内): + - **SUmgMcpMessageInteractionHub**:外层容器。 + - **SUmgMcpUserMessageWidget**:UserMessageWidget 用户消息呈现。 + - **SUmgMcpAgentResponseGroup**:AgentTurn / 活跃 Agent 消息承载组。 + - **SUmgMcpTaskBeginNode / SUmgMcpTaskEndNode**:TaskInteractionNode 任务流向卡片。 + - **SUmgMcpToolExecutionBlock**:ToolExecutionBlock 纯粹的工具请求审批队列卡片。 + +### 2.1 审计结论:`MessageList` 不是独立架构概念 +- `MessageList` 这个词太模糊,容易把“窗口消息面”误解成“某个消息集合容器”或“某一条消息列表”。 +- 不应再使用 `SUmgMcpChatList` 或者 `SUmgMcpSessionMessageSurface`,直接命名为 `SUmgMcpMessageInteractionHub`,其子组件全部放入 `MessageInteractionHub` 文件夹。 + +### 3. ChatMessage(单条活消息) +- 一条消息是一个活体对象,受 `StartNewChatMessage` 控制归档。 +- 只有一个当前活跃对象负责监听后端状态变化。 +- 历史消息归档后应只读。 + +### 4. TaskMessage(Task 概念) +- `task_begin` / `task_end` 是独立任务概念,不应混入普通 ChatMessage。 +- 它们在 UI 上应作为单独节点出现,并由 TaskSubsystem 的委托/状态驱动。 +- ChatWindow 不能自己完成 task_begin;它只能转发审批和监听后端任务节点变化。 +- `FunctionCallWidgetList` 只承载普通 MCP function call;`task_begin` 必须在进入普通审批队列之前被剥离出来。 + +### 5. MCPApprovalSurface(MCP 审批面) +- 一组 MCP 请求按顺序呈现。 +- 当前审查点可以展开详细参数。 +- 审批动作只向后端发出,不由前端替代后端决策。 + +### 6. BackendEventBridge(后端事件桥) +- 前端只订阅后端状态变化。 +- 任何状态更新都应通过委托/广播到达当前活跃消息或对应的任务/MCP UI。 + +## 高风险目录审计结论 + +### 已移除目录 +- `Flow/`:已删除。 +- `Learning/`:已删除。 +- `Policies/`:已从 ChatWindow 目录移除,rate-limit 逻辑已迁入 AIProvider 侧。 +- `MessageList/UmgMcpMessageListItemRouter`:已删除,消息面直接按概念创建和更新活跃消息承载体。 + +### 仍需保留审计视角的内部实现 +- `UmgMcpToolMessageStateMapper`:纯状态映射工具,可以保留为内部实现,但不应提升为架构中心。 + +## 当前实现映射(仅作为审计对象) +## 当前实现映射(仅作为审计对象) +- `SUmgMcpChatWindow`:窗口入口。 +- `SUmgMcpMessageInteractionHub`:当前承载消息面。 +- `SUmgMcpAgentResponseGroup`:当前活跃 AgentResponseGroup 的 UI 承载对象。 +- `SUmgMcpTaskBeginNode` / `SUmgMcpTaskEndNode`:TaskInteractionNode 的 UI 节点。 +- `SUmgMcpToolExecutionBlock`:ToolExecutionBlock 审批节点。 +- `SUmgMcpUserMessageWidget`:UserMessageWidget。 +- `UUmgMcpTaskSubsystem`:Task 节点与队列的后台权威入口。 +- `UUmgMcpActiveMessageSubsystem`:处理 Agent 对话流程、状态管理。**(已由 UUmgMcpChatSystemSubsystem 重命名并修改集成完毕)**。 +- `IUmgMcpAiProvider`:rate-limit 判断与提示已迁入 provider 基类。 + +## 一一映射表(概念到代码) + +| 概念名称 | 代码类名 | 语义说明 | +|----------|----------|----------| +| ChatWindow | SUmgMcpChatWindow | 顶级窗口容器,负责整体布局和事件转发 | +| TopBar | SUmgMcpChatTopBar | 顶栏组件,显示工具和状态 | +| Welcome | SUmgMcpChatWelcome | 欢迎页/历史列表组件 | +| ActiveMessageSubsystem | UUmgMcpActiveMessageSubsystem | 活跃对话协调器子系统 | +| BottomBar | SUmgMcpChatInput | 底部输入区,处理用户输入和模式切换 | +| UserMessageWidget | SUmgMcpUserMessageWidget | 用户消息显示组件 | +| AgentResponseGroup | SUmgMcpAgentResponseGroup | AI响应组,包含文字和MCP模块 | +| TaskInteractionNode | SUmgMcpTaskBeginNode / SUmgMcpTaskEndNode | 任务交互节点,开始和结束 | +| SystemNotificationWidget | (缺失) | 系统提示/错误恢复组件 | +| ToolExecutionBlock | SUmgMcpToolExecutionBlock | 工具执行块,MCP审批,受后端严格组装控制 | + +## 必须警惕的强盗化迹象 +- 名字不在规则文档中,却参与了主流程。 +- 只是参数转发,却被包装成独立概念。 +- 由 UI 持有了本该由后端决定的状态。 +- 把一个活跃消息误写成多个消息容器。 +- 把任务、MCP、消息混写成同一层概念。 +- 把实现细节命名成概念中心,反过来让文档为它背书。 + +## 删除 / 合并原则 +- 只承担中转且没有独立概念的文件,应优先合并或删除。 +- 任何不属于窗口入口、消息面、单条消息、任务消息、MCP 审批面、会话保存、事件桥的内容,都应被视为架构外。 +- 若一个类只是为了拆分而拆分,不承载独立概念,应优先重命名为可理解的边界名,或直接删除。 diff --git a/Document/CodexInstall.md b/Document/CodexInstall.md new file mode 100644 index 0000000..35440b1 --- /dev/null +++ b/Document/CodexInstall.md @@ -0,0 +1,91 @@ +# Install UMG MCP for Codex + +Codex supports MCP servers through `config.toml` or `codex mcp add`. The installer in this repository registers the UMG MCP Python server as a Codex STDIO MCP server. + +## Requirements + +- Codex CLI or Codex desktop/IDE using the same `~/.codex/config.toml`. +- `uv` available on `PATH`. +- Unreal Editor running with this plugin loaded when you want to call UMG tools. + +## One-command install + +From this plugin root: + +```powershell +.\Scripts\Install-CodexUmgMcp.ps1 +``` + +This registers: + +```toml +[mcp_servers.umg-mcp] +command = "uv" +args = ["run", "--directory", "...\Resources\Python", "UmgMcpServer.py"] +startup_timeout_sec = 20 +tool_timeout_sec = 120 +enabled = true +``` + +Use a custom plugin path: + +```powershell +.\Scripts\Install-CodexUmgMcp.ps1 -PluginRoot "D:\Path\To\Project\Plugins\FabUmgMcp" +``` + +Install into a project-scoped Codex config instead of the user config: + +```powershell +.\Scripts\Install-CodexUmgMcp.ps1 -Scope project +``` + +Project-scoped config only loads after the project is trusted in Codex. User-level install is the recommended default. + +## Verify + +Restart Codex or open a new session, then run `/mcp` in Codex. You should see `umg-mcp`. + +If the server starts but tool calls fail, confirm Unreal Editor is open and the UMG MCP plugin is listening on the host/port configured in `Resources/Python/mcp_config.py`. + +## Use Codex As A FabServer AI Provider + +The MCP install above lets Codex call UMG MCP tools. The plugin can also expose Codex as a FabServer AI provider by launching an installed Codex CLI through `codex exec`. + +This does not make ChatUI route around FabServer. ChatUI still sends messages to FabServer, and FabServer chooses the active `IUmgMcpAiProvider`. + +In **Project Settings > Plugins > Unreal Motion Graphics MCP > McpCli**, set: + +```text +LocalCliProvider = Codex CLI +LocalCliCommand = codex +``` + +Then set **MultiRetry > PrimaryProvider** to: + +```text +Codex CLI +``` + +If the Codex desktop WindowsApps executable cannot be launched from other processes, install or expose a standalone CLI command and point `LocalCliCommand` to it, for example: + +```text +LocalCliCommand = npx -y @openai/codex +``` + +The FabServer provider runs: + +```text +codex exec --ephemeral --sandbox read-only +``` + +This is intentionally read-only and returns text through the normal FabServer provider response path. + +## Authentication Boundary + +Do not implement a separate ChatGPT account login inside this plugin for Codex. Public Codex documentation describes ChatGPT sign-in and API-key auth for Codex's own surfaces, but it does not document a third-party Unreal plugin flow for reusing or exchanging a ChatGPT login session. + +Supported integration paths are: + +- Codex CLI provider: use an installed, already-authenticated `codex` command. +- Codex MCP consumer: install `umg-mcp` so Codex can call UMG MCP tools. +- OpenAI-compatible API provider: use an API key through the plugin's existing API provider settings if you want direct model API calls instead of Codex. diff --git a/Document/FabServer_Checklist.md b/Document/FabServer_Checklist.md new file mode 100644 index 0000000..5af752f --- /dev/null +++ b/Document/FabServer_Checklist.md @@ -0,0 +1,76 @@ + +## 概念 + +send:原子操作,一个网络请求,输入消息,返回消息;AI provider只提供了这个。注意:任何让AIprovider提供非send的功能的,都是强盗代码,直接删掉。 +agent:对话对象,具有chat属性。 +- agent自己管理对话历史信息。看到非agent的管理上下文信息直接删除即可。 +- agent自己实现的chat,agent自己注册的MCP,agent自己实现的chat(send-mcp-send)循环。看到有MCP信息不是在agent里面实现的直接删掉即可 +chat:对话,包含一个或多个send-mcp-send循环。chat实现的MCP逻辑,看到不是在chat里面搞的Send-MCP-send逻辑直接删掉即可。 +task:任务系统,在chat end后,由task系统检查是否有task存在进而决定是否拉起其他agent继续chat +FunctionCallWidgetList:一个Functon call的队列UI。原则上后端不得直接请求MCP结果,因为权限问题。原则上所有的后端MCP请求会转变为前端FunctionCallWidgetList,由用户或者扩展的东西决定MCP是否运行。 + + + + + +## 状态约束 + +- 全局只允许一个活跃 chat in-flight。 +- 前端状态以按钮语义表达:Send / Interrupt(支持 3 秒二次中断确认)。 +- MCP function call 默认不同意,必须先经 UI 卡片审批后逐项串行执行;进入 UI 审批前必须先判断 FunctionCallWidgetList 是否为空。 +- `task_begin/task_end` 是 task 系统委托,不进入普通 `FunctionCallWidgetList` 审批路径。 + +## 节点与代码对应关系 + +| 流程节点 | 主要代码入口 | +| --- | --- | +| User 输入消息 | `SBottomBar::OnSendClicked` (直接调用 StartNewChatMessage 定界) | +| 发送按钮切换到 Interrupt | UI 订阅 `UUmgMcpActiveMessageSubsystem::OnActiveStateChanged` 自主切换 | +| 确定对话对象(是否 @agent) | `UUmgMcpTaskSubsystem::ResolveAnswerForQuestion` | +| 获取的agent为answer,并通知Task系统 | `UUmgMcpTaskSubsystem::NotifyAgentAnswer` | +| 从Task系统获得agent为answer | `UUmgMcpTaskSubsystem::GetAgentForQuestion` | +| 更新当前活跃消息的头像、名字等 | `UUmgMcpActiveMessageSubsystem::UpdateActiveMessageMeta` | +| Provider.send 发送 | `IUmgMcpAiProvider::Send` | +| status=thinking | `UUmgMcpActiveMessageSubsystem::MarkThinking` | +| Provider.receive 接收 | `IUmgMcpAiProvider::Receive` | +| 先添加 receive 消息到消息中 | `UUmgMcpActiveMessageSubsystem::AddReceiveMessage` | +| 获取 function call 列表 | `UUmgMcpFunctionCallSubsystem::ExtractFunctionCalls` | +| 初始化 FunctionCallWidgetList | `UUmgMcpFunctionCallSubsystem::InitFunctionCallWidgetList` | +| for each function call | `UUmgMcpFunctionCallSubsystem::ProcessEachFunctionCall` | +| 是否是 task begin? | `UUmgMcpFunctionCallSubsystem::IsTaskBeginFunctionCall` | +| TaskSubsystem 委托 Task 节点 | `UUmgMcpTaskSubsystem::HandleTaskBegin` | +| 添加到 FunctionCallWidgetList | `UUmgMcpFunctionCallSubsystem::AddToFunctionCallWidgetList` | +| 所有的FunctionCallWidgetList构建一个MCP审批队列UI | `UUmgMcpFunctionCallSubsystem::BuildMcpApprovalUI` | +| UI添加到消息中(如果是空的则不添加),进入 UI 审批 | `UUmgMcpFunctionCallSubsystem::AddApprovalUIToMessage` | +| status=wait MCP | `UUmgMcpActiveMessageSubsystem::MarkWaitingMcp` | +| 用户审批当前 FunctionCall | `SUmgMcpToolMessage::OnApproveOnceClicked` | +| status=MCP running | `UUmgMcpActiveMessageSubsystem::MarkMcpRunning` | +| FunctionCallWidgetList 是否全部审批完? | `UUmgMcpFunctionCallSubsystem::IsFunctionCallWidgetListApproved` | +| FunctionCallWidgetList 是否为0? | `UUmgMcpFunctionCallSubsystem::IsFunctionCallWidgetListEmpty` | +| chat end 调用StartNewChatMessage | `UUmgMcpActiveMessageSubsystem::EndChatAndStartNew` | +| 任务入口? | `UUmgMcpTaskSubsystem::HasTaskBeginPending` | +| TaskSubsystem 完成 Task 节点并进入 accept/reject | `UUmgMcpTaskSubsystem::ProcessTaskBegin` | +| 任务结束候选 | `UUmgMcpTaskSubsystem::HasTaskEndCandidate` | +| TaskEnd UI: accept/reject/later | `TheTaskEndMessage::OnAcceptClicked` | +| 消费当前 task/agent | `UUmgMcpTaskSubsystem::ConsumeCurrentTask` | +| 移动到队列末尾 | `UUmgMcpTaskSubsystem::MoveToQueueEnd` | +| 恢复用户send按钮等待用户消息 | UI 订阅 `UUmgMcpActiveMessageSubsystem::OnActiveMessageCleared` 自主恢复 | +| 任务结束候选 | `UUmgMcpTaskSubsystem::HasTaskEndCandidate` | +| TaskEnd UI: accept/reject/later | `TheTaskEndMessage::OnAcceptClicked` | +| 消费当前 task/agent | `UUmgMcpTaskSubsystem::ConsumeCurrentTask` | +| 移动到队列末尾 | `UUmgMcpTaskSubsystem::MoveToQueueEnd` | +| 恢复用户send按钮等待用户消息 | `SUmgMcpChatWindow::ResetSendButton` | + +## 守恒约束(简化原则) + +- task_begin 只负责把任务入口交给 TaskSubsystem,不允许 UI 自己消化或自结束。 +- task_end 只负责“释放已开始任务/弹栈回到上游 agent”。 +- 系统始终遵循“先 begin 一一成立,再 end 一一释放”的守恒关系。 + +## Save/Resume 检查点(用于网络失败恢复) + +- Checkpoint A: 发起 send 前(输入、agent、tool_mode、当前 history 快照) +- Checkpoint B: 每个 MCP 完成后(MCP 队列索引、工具结果) +- Checkpoint C: chat 结束时(response/error、task_begin pending 列表、task 栈、FunctionCallWidgetList 归档状态) +- Resume 入口:加载会话时恢复 history + task runtime,按 pending 队列继续串联流程 + diff --git a/Document/FabServer_DeleteChecklist.md b/Document/FabServer_DeleteChecklist.md new file mode 100644 index 0000000..03529e0 --- /dev/null +++ b/Document/FabServer_DeleteChecklist.md @@ -0,0 +1,35 @@ +# FabServer 删除清单 + +> 依据:`FabServer_SerialFlow.md` 与 `.github/copilot-instructions.md` +> +> 原则:只保留符合“send 在 AIProvider、chat/MCP 在 chat/agent、task_begin/task_end 归 task 系统”的代码。其余直接删除,不做兼容性保留。 + +## 必删项 + +1. Provider 内部的工具执行闭环 +- 任何在 AIProvider 中直接解析 function call 并立即执行工具的代码。 +- 任何 provider 内部递归调用自身来继续处理 tool call 的代码。 +- 任何把 `task_begin` / `task_end` 当作 provider 侧普通工具执行的代码。 + +2. Provider 内部的 task 强hold +- 任何 provider 直接调用 `TaskProtocolToolExecutor` 的代码。 +- 任何 provider 自己决定 task begin / task end / agent 切换的代码。 + +3. 混入 provider 的聊天状态控制 +- 任何 provider 维护 `thinking / wait MCP / MCP running / completed` 这类 UI 状态的代码。 +- 任何 provider 维护普通消息审批队列的代码。 + +4. 非文档化的中间层强hold +- 任何不在 `FabServer_SerialFlow.md` 节点表中的中间 executor、dispatcher、batch executor。 +- 任何把普通 MCP 与 task_begin/task_end 合并到同一审批队列的代码。 + +5. 残余耦合引用 +- 已删除/已废弃符号的残余调用、包含和绑定。 +- 与当前架构无关的“兼容性”、旧流程、重复参数、重复状态字段。 + +## 删除顺序 + +1. 先删 provider 侧直执行工具链。 +2. 再删 task 强hold 执行入口。 +3. 然后复查 chat window / session surface / subsystem 的残余引用。 +4. 最后编译验证。 diff --git a/Document/FabServer_SerialFlow.md b/Document/FabServer_SerialFlow.md new file mode 100644 index 0000000..a2096f0 --- /dev/null +++ b/Document/FabServer_SerialFlow.md @@ -0,0 +1,148 @@ +# FabServer 串联流程(小并列,大串联) + +> 详细说明请分别查看: +> - [ChatMessage 生命周期(前端展示视角)](ChatMessage_Lifecycle.md) +> - [ChatWindow 理论架构图(目录与职责边界)](ChatWindow_Architecture.md) + +```mermaid +flowchart TD + U[User 输入消息] --> FE_SEND[SBottomBar::OnSendClicked 触发] + FE_SEND --> START_NEW_CHAT_MSG[ActiveMessageSubsystem::StartNewChatMessage 定界] + subgraph DIALOG_TARGET[确定对话对象] + START_NEW_CHAT_MSG --> BE_DECIDE{GetNowAnswer: 消息是否@agent?} + BE_DECIDE --是--> BE_AT_AGENT[获取的agent为answer,并通知Task系统] + BE_DECIDE --否--> BE_TASK_AGENT[从Task系统获得agent为answer] + BE_AT_AGENT --> UPDATE_CHAT_META[更新当前活跃消息的头像、名字等] + BE_TASK_AGENT --> UPDATE_CHAT_META + end + UPDATE_CHAT_META --> CHAT_BEGIN + + subgraph CHAT_FLOW[AgentAnswerChatMessageSubsystem消息处理(agent chat 内部逻辑)] + CHAT_BEGIN[chat begin] + subgraph AGENT_ANSWER[agent内部answer] + CHAT_BEGIN --> CHAT_SEND[Provider.send 发送] + CHAT_SEND --> STATUS_THINKING[status=thinking] + STATUS_THINKING --> CHAT_RECEIVE[Provider.receive 接收] + CHAT_RECEIVE --> ADD_RECEIVE_MSG[先添加 receive 消息到消息中] + ADD_RECEIVE_MSG --> FCALL_LIST[获取 function call 列表] + FCALL_LIST --> FCWIDGET_LIST[初始化 FunctionCallWidgetList] + FCWIDGET_LIST --> FCALL_LOOP + FCALL_LOOP --> IS_TASK_BEGIN{是否是 task begin?} + IS_TASK_BEGIN -->|是| TASK_NODE[TaskSubsystem 委托 Task 节点,注意,这里没写添加到FunctionCallWidgetList中] + TASK_NODE --> FCALL_LOOP + SEND_LOOP_DECIDE -->|是| CHAT_END[chat end 调用StartNewChatMessage] + SEND_LOOP_DECIDE -->|否| CHAT_SEND + end + subgraph FUNCTION_CALL_SUBSYSTEM[Function call subsystem] + IS_TASK_BEGIN -->|否| ADD_TO_WIDGET[添加到 FunctionCallWidgetList] + ADD_TO_WIDGET --> FCALL_LOOP + FCALL_LOOP -->|全部处理| ADD_WIDGET_TO_MSG[所有的FunctionCallWidgetList构建一个MCP审批队列UI(看清楚,FunctionCallWidgetList构建的时候task begin根本就没添加进来是)] + ADD_WIDGET_TO_MSG --> UI_APPROVAL[UI添加到消息中(如果是空的则不添加),进入 UI 审批] + STATUS_MCP_RUNNING --> FCWIDGET_DONE + UI_APPROVAL --> FCWIDGET_DONE + FCWIDGET_DONE{FunctionCallWidgetList 是否全部审批完?} + FCWIDGET_DONE -- 是 --> SEND_LOOP_DECIDE{FunctionCallWidgetList 是否为0? 或者 本轮是否有task begin} + FCWIDGET_DONE -- 否 --> STATUS_WAIT_MCP + STATUS_WAIT_MCP[status=wait MCP] + STATUS_WAIT_MCP --> USER_APPROVE[用户审批当前 FunctionCall] + USER_APPROVE --> STATUS_MCP_RUNNING[status=MCP running] + end + end + + CHAT_END --> TASK_BEGIN_UI + subgraph TASK_FLOW[Task处理] + TASK_BEGIN_UI{是否存在 task_begin 任务入口?} + TASK_BEGIN_UI -->|否| TASK_END_UI{是否存在 task_end 候选} + TASK_BEGIN_UI -- 是 --> BEGIN_DECIDE[TaskSubsystem 完成 Task 节点并进入 accept/reject] + BEGIN_DECIDE -- accept --> BE_TASK_AGENT + + TASK_END_UI -->|是| END_DECIDE[TaskEnd UI: accept/reject/later] + END_DECIDE -->|accept| END_CONSUME[消费当前 task/agent] + END_DECIDE -->|later| END_ROTATE[移动到队列末尾] + + END_CONSUME --> TASK_END_UI + END_ROTATE --> TASK_END_UI + end + + BEGIN_DECIDE -- reject --> RETURN_USER + TASK_END_UI -->|否| RETURN_USER + END_DECIDE -->|reject| RETURN_USER + RETURN_USER([恢复用户send按钮等待用户消息]) + +``` + +## 概念 + +send:原子操作,一个网络请求,输入消息,返回消息;AI provider只提供了这个。注意:任何让AIprovider提供非send的功能的,都是强盗代码,直接删掉。 +agent:对话对象,具有chat属性。 +- agent自己管理对话历史信息。看到非agent的管理上下文信息直接删除即可。 +- agent自己实现的chat,agent自己注册的MCP,agent自己实现的chat(send-mcp-send)循环。看到有MCP信息不是在agent里面实现的直接删掉即可 +chat:对话,包含一个或多个send-mcp-send循环。chat实现的MCP逻辑,看到不是在chat里面搞的Send-MCP-send逻辑直接删掉即可。 +task:任务系统,在chat end后,由task系统检查是否有task存在进而决定是否拉起其他agent继续chat +FunctionCallWidgetList:一个Functon call的队列UI。原则上后端不得直接请求MCP结果,因为权限问题。原则上所有的后端MCP请求会转变为前端FunctionCallWidgetList,由用户或者扩展的东西决定MCP是否运行。 + + + + + +## 状态约束 + +- 全局只允许一个活跃 chat in-flight。 +- 前端状态以按钮语义表达:Send / Interrupt(支持 3 秒二次中断确认)。 +- MCP function call 默认不同意,必须先经 UI 卡片审批后逐项串行执行;进入 UI 审批前必须先判断 FunctionCallWidgetList 是否为空。 +- `task_begin/task_end` 是 task 系统委托,不进入普通 `FunctionCallWidgetList` 审批路径。 + +## 节点与代码对应关系 + +| 流程节点 | 主要代码入口 | +| --- | --- | +| User 输入消息 | `SBottomBar::OnSendClicked` (直接调用 StartNewChatMessage 定界) | +| 发送按钮切换到 Interrupt | UI 订阅 `UUmgMcpActiveMessageSubsystem::OnActiveStateChanged` 自主切换 | +| 确定对话对象(是否 @agent) | `UUmgMcpTaskSubsystem::ResolveAnswerForQuestion` | +| 获取的agent为answer,并通知Task系统 | `UUmgMcpTaskSubsystem::NotifyAgentAnswer` | +| 从Task系统获得agent为answer | `UUmgMcpTaskSubsystem::GetAgentForQuestion` | +| 更新当前活跃消息的头像、名字等 | `UUmgMcpActiveMessageSubsystem::UpdateActiveMessageMeta` | +| Provider.send 发送 | `IUmgMcpAiProvider::Send` | +| status=thinking | `UUmgMcpActiveMessageSubsystem::MarkThinking` | +| Provider.receive 接收 | `IUmgMcpAiProvider::Receive` | +| 先添加 receive 消息到消息中 | `UUmgMcpActiveMessageSubsystem::AddReceiveMessage` | +| 获取 function call 列表 | `UUmgMcpFunctionCallSubsystem::ExtractFunctionCalls` | +| 初始化 FunctionCallWidgetList | `UUmgMcpFunctionCallSubsystem::InitFunctionCallWidgetList` | +| for each function call | `UUmgMcpFunctionCallSubsystem::ProcessEachFunctionCall` | +| 是否是 task begin? | `UUmgMcpFunctionCallSubsystem::IsTaskBeginFunctionCall` | +| TaskSubsystem 委托 Task 节点 | `UUmgMcpTaskSubsystem::HandleTaskBegin` | +| 添加到 FunctionCallWidgetList | `UUmgMcpFunctionCallSubsystem::AddToFunctionCallWidgetList` | +| 所有的FunctionCallWidgetList构建一个MCP审批队列UI | `UUmgMcpFunctionCallSubsystem::BuildMcpApprovalUI` | +| UI添加到消息中(如果是空的则不添加),进入 UI 审批 | `UUmgMcpFunctionCallSubsystem::AddApprovalUIToMessage` | +| status=wait MCP | `UUmgMcpActiveMessageSubsystem::MarkWaitingMcp` | +| 用户审批当前 FunctionCall | `SUmgMcpToolMessage::OnApproveOnceClicked` | +| status=MCP running | `UUmgMcpActiveMessageSubsystem::MarkMcpRunning` | +| FunctionCallWidgetList 是否全部审批完? | `UUmgMcpFunctionCallSubsystem::IsFunctionCallWidgetListApproved` | +| FunctionCallWidgetList 是否为0? | `UUmgMcpFunctionCallSubsystem::IsFunctionCallWidgetListEmpty` | +| chat end 调用StartNewChatMessage | `UUmgMcpActiveMessageSubsystem::EndChatAndStartNew` | +| 任务入口? | `UUmgMcpTaskSubsystem::HasTaskBeginPending` | +| TaskSubsystem 完成 Task 节点并进入 accept/reject | `UUmgMcpTaskSubsystem::ProcessTaskBegin` | +| 任务结束候选 | `UUmgMcpTaskSubsystem::HasTaskEndCandidate` | +| TaskEnd UI: accept/reject/later | `TheTaskEndMessage::OnAcceptClicked` | +| 消费当前 task/agent | `UUmgMcpTaskSubsystem::ConsumeCurrentTask` | +| 移动到队列末尾 | `UUmgMcpTaskSubsystem::MoveToQueueEnd` | +| 恢复用户send按钮等待用户消息 | UI 订阅 `UUmgMcpActiveMessageSubsystem::OnActiveMessageCleared` 自主恢复 | +| 任务结束候选 | `UUmgMcpTaskSubsystem::HasTaskEndCandidate` | +| TaskEnd UI: accept/reject/later | `TheTaskEndMessage::OnAcceptClicked` | +| 消费当前 task/agent | `UUmgMcpTaskSubsystem::ConsumeCurrentTask` | +| 移动到队列末尾 | `UUmgMcpTaskSubsystem::MoveToQueueEnd` | +| 恢复用户send按钮等待用户消息 | `SUmgMcpChatWindow::ResetSendButton` | + +## 守恒约束(简化原则) + +- task_begin 只负责把任务入口交给 TaskSubsystem,不允许 UI 自己消化或自结束。 +- task_end 只负责“释放已开始任务/弹栈回到上游 agent”。 +- 系统始终遵循“先 begin 一一成立,再 end 一一释放”的守恒关系。 + +## Save/Resume 检查点(用于网络失败恢复) + +- Checkpoint A: 发起 send 前(输入、agent、tool_mode、当前 history 快照) +- Checkpoint B: 每个 MCP 完成后(MCP 队列索引、工具结果) +- Checkpoint C: chat 结束时(response/error、task_begin pending 列表、task 栈、FunctionCallWidgetList 归档状态) +- Resume 入口:加载会话时恢复 history + task runtime,按 pending 队列继续串联流程 + diff --git a/Document/Google_OAuth_Setup.md b/Document/Google_OAuth_Setup.md new file mode 100644 index 0000000..e3749b0 --- /dev/null +++ b/Document/Google_OAuth_Setup.md @@ -0,0 +1,34 @@ +# Google OAuth 2.0 配置指南 (Winyunq Style) + +为了启用插件的身份验证功能(如用户头像、个性化欢迎语等),您需要配置自己的 Google OAuth 凭据。 + +## 步骤 1:创建 Google Cloud 项目 +1. 访问 [Google Cloud Console](https://console.cloud.google.com/)。 +2. 创建一个新项目,命名为 `FabUmgMcp` 或您喜欢的名称。 + +## 步骤 2:启用 API 服务 +1. 在左侧菜单中选择 **API 和服务** > **库**。 +2. 搜索并启用 **Generative Language API** (供 Gemini 使用)。 + +## 步骤 3:配置 OAuth 同意屏幕 +1. 在左侧菜单中选择 **API 和服务** > **OAuth 同意屏幕**。 +2. 选择 **User Type**: **外部 (External)** (如果您有 Google Workspace,也可以选择内部)。 +3. 填写必要应用信息(名称、支持邮箱)。 +4. 在 **范围 (Scopes)** 中添加:`.../auth/generative-language` 和 `userinfo.profile`。 +5. 将您的测试账号 (Gmail) 添加到 **测试用户** 列表中。 + +## 步骤 4:创建凭据 (Credentials) +1. 在左侧菜单中选择 **凭据**。 +2. 点击 **创建凭据** > **OAuth 客户端 ID**。 +3. **应用类型** 选择 **桌面应用 (Desktop App)**。 +4. 创建后,您将获得 **客户端 ID (Client ID)** 和 **客户端密钥 (Client Secret)**。 + +## 步骤 5:在代码中填入凭据 +1. 打开文件:`Source/UmgMcp/Private/FabServer/Authentication/UmgMcpGoogleAuthenticationProvider.h`。 +2. 将获取到的 `ClientID` 和 `ClientSecret` 填入对应的变量中。 + - `ClientID`: `YOUR_CLIENT_ID.apps.googleusercontent.com` + - `ClientSecret`: `YOUR_CLIENT_SECRET` +3. 重新编译 Unreal Engine 项目。 + +--- +*注:由于 Winyunq 战略强调安全性与开发者掌控,我们目前不建议将 Secret 存储在 Editor Config 文件中。* diff --git a/Document/LogarithmicImageScalingTheory.md b/Document/LogarithmicImageScalingTheory.md new file mode 100644 index 0000000..bae0c86 --- /dev/null +++ b/Document/LogarithmicImageScalingTheory.md @@ -0,0 +1,166 @@ +# 基于自然对数亚线性压缩的 GUI 图像附件自适应缩放理论与 Slate C++ 实现 + +## 1. 研究背景与设计痛点 + +在现代多模态大模型(Multimodal LLM)交互的客户端设计中,富文本输入与图片附件的混合输入已成为标准工作流。然而,在基于 Unreal Engine Slate 框架的 C++ 插件开发中,对待发送图片进行实时 UI 预览通常面临以下三项严峻的工程与视觉痛点: + +1. **排版物理冲击(Layout Blowup)**:直接以图片的原始物理分辨率进行等比渲染,会导致高分辨率大图瞬间挤占并撑爆有限的对话框排版空间; +2. **特征丢失与失真(Semantic Loss & Distortion)**:采用传统的“强制固定长宽”(如 $64\times 64$ 硬裁剪或强行压实)会打破图片的原始宽高比,导致严重的拉伸形变,使用户无法辨识图片内的关键文字与语义细节; +3. **Slate 弱生命周期贴图被 GC 回收崩溃(Slate GC Vulnearbility)**:Slate 控件属于纯 C++ 智能指针体系,不参与虚幻反射与垃圾回收(Garbage Collection)强引用计数。在 Paint/Brush 阶段如果动态引入的 `UTexture2D` 没有受到全局 `UPROPERTY()` 的反射保护,在下一帧垃圾回收触发时,贴图资源会被强行释放,导致底层的显卡渲染指针变为空野指针,引发编辑器崩溃(Crash)。 + +为了彻底解决上述痛点,本文提出了一套结合 **“自然对数亚线性非线性压缩”**、**“长宽比精确锁定”**、**“输入编辑光标隐式双向联动”** 与 **“Subsystem 全局反射 GC 防御层”** 的工业级 C++ Slate 排版解决方案。 + +--- + +## 2. 自然对数非线性缩放数学模型 + +### 2.1 亚线性非线性压缩公式 (Sublinear Non-linear Compression) + +为了让低分辨率的小图保持原大小不缩水,同时让高分辨率的大图尺寸受到亚线性平滑压缩、不致过分撑开 UI,我们引入以自然常数 $e$ 为底的**自然对数非线性收缩公式**。 + +设图片的最小边为 $M = \min(W, H)$,定义最小边界基准尺寸为 $S_{\text{base}}$(在 Slate 设计中通常取单行字符高度的大致物理尺寸,如 $64.0\text{px}$)。 + +缩放因子 $\text{Scale}(M)$ 的数学定义如下: + +$$\text{Scale}(M) = \begin{cases} +1.0, & 0 < M \le S_{\text{base}} \\ +1.0 + \ln\left(\frac{M}{S_{\text{base}}}\right), & M > S_{\text{base}} +\end{cases}$$ + +则经过自适应对数压缩后的目标最小边尺寸 $T$ 为: + +$$T = S_{\text{base}} \times \text{Scale}(M)$$ + +为了满足严苛的布局上限,我们对目标最小边施加一个物理硬上限 $T_{\text{max}}$(通常设计为 $120.0\text{px}$ 或 $180.0\text{px}$,视具体气泡/预览容器而定),即: + +$$T_{\text{final}} = \text{Clamp}(S_{\text{base}} \times \text{Scale}(M), S_{\text{base}}, T_{\text{max}})$$ + +--- + +### 2.2 亚线性收敛与数学证明 + +我们对对数压缩函数 $f(M) = S_{\text{base}} \cdot \left[1.0 + \ln\left(\frac{M}{S_{\text{base}}}\right)\right]$ 进行导数分析,以证明其在数学上的优越表现。 + +#### 1) 单调性(Monotonicity)证明 +对其求一阶导数: + +$$f'(M) = S_{\text{base}} \cdot \frac{d}{dM} \left[1.0 + \ln(M) - \ln(S_{\text{base}})\right] = S_{\text{base}} \cdot \frac{1}{M} > 0 \quad (\forall M > 0)$$ + +由于其一阶导数在定义域内恒大于零,证明该缩放函数**严格单调递增**。这确保了输入大图对应的缩略图永远大于或等于输入小图,不会出现尺寸倒挂的视觉异常。 + +#### 2) 凹性(Concavity)与凹增性证明 +对其求二阶导数: + +$$f''(M) = \frac{d}{dM}\left(\frac{S_{\text{base}}}{M}\right) = -\frac{S_{\text{base}}}{M^2} < 0 \quad (\forall M > 0)$$ + +由于其二阶导数恒小于零,证明该曲线为**凸向上的凹函数**。物理意义上,其增长斜率随着原始图片尺寸 $M$ 的增加而迅速递减(即边际递减效应)。 +这表明该算法在保证信息量增加的同时,物理空间增量收敛,完美压制了超大图对 GUI 布局的物理冲击,实现了极其柔和且弹性的非线性过渡。 + +--- + +### 2.3 宽高比精确锁定 (Aspect Ratio Lock) + +在推算出目标最小边 $T_{\text{final}}$ 后,为了避免图像在水平或垂直方向产生拉伸形变,我们必须精确锁定其原始宽高比: + +$$\text{Ratio} = \frac{W}{H}$$ + +最终渲染的二维画刷尺寸向量 $\mathbf{Size} = (W_{\text{final}}, H_{\text{final}})$ 推导公式如下: + +$$\mathbf{Size} = \begin{cases} +(T_{\text{final}}, \frac{T_{\text{final}}}{\text{Ratio}}), & W \le H \quad (\text{Portrait/Square}) \\ +(T_{\text{final}} \times \text{Ratio}, T_{\text{final}}), & W > H \quad (\text{Landscape}) +\end{cases}$$ + +这使得长边根据宽高比自由延伸,完美消除了拉伸感,保留了图像所有的纵横视觉特征。 + +--- + +## 3. Slate 隐式标记联动与双向编辑流 + +为了向底层 `litert-unreal` 大模型引擎传递图片与文本之间的精确定位关系,我们在纯文本框(SMultiLineEditableTextBox)中隐式引入可被 AI Provider 感知的结构化富文本占位符: + +```xml +imageN +``` + +这一整套架构的输入、预览、渲染与联动流程如下: + +```mermaid +graph TD + A[拖拽/粘贴/外部选择图片] --> B{ChatInput 维护局部 Counter} + B -->|例如分配 image1| C[在光标编辑处插入 LocalTag 控制标签] + B -->|AddAttachment 信号传递| D[SUmgMcpAttachmentList 动态生成对数 Brush] + D --> E[下方预览栏渲染完成] + E -->|点击右上角 × 联动删除| F[发布 NotifyAttachmentRemoved 委托广播] + F -->|ChatInput 独立监听| G[编辑框自身清洗对应 XML 标记] + F -->|AttachmentList 自身更新| H[物理项同步出栈且释放 brush 资源] +``` + +### 3.1 联动删除的 C++ 高级实现 +当用户在预览框点击删除按钮时,系统会自动调取已注册的 `ChatInput` 控件,执行原子级字符串扫描替换,这避免了由于复杂光标删除导致的历史崩溃: + +```cpp +void SUmgMcpChatInput::RemoveImageTag(const FString& InImageId) +{ + if (InputTextBox.IsValid()) + { + FString CurrentText = InputTextBox->GetText().ToString(); + FString TargetTag = FString::Printf(TEXT("%s"), *InImageId); + + // 精确清除编辑框中的特定隐式标记,而完全保留用户手打的其他文本内容 + CurrentText = CurrentText.Replace(*TargetTag, TEXT("")); + InputTextBox->SetText(FText::FromString(CurrentText)); + } +} +``` + +--- + +## 4. 全局反射 GC 防御层架构设计 + +为了保证贴图生命周期在 Slate 渲染回路中的绝对安全,`UUmgMcpActiveMessageSubsystem` 在 UObject 堆内存中开辟了一块由垃圾回收器托管的强引用缓存区域: + +```cpp +UPROPERTY() +TMap> PreviewTextureCache; +``` + +每次从 Base64 编码载入贴图并进行预览或在历史气泡渲染时,都会通过 `GetOrCreateDynamicTexture` 获取已强引用的贴图句柄: + +```cpp +UTexture2D* UUmgMcpActiveMessageSubsystem::GetOrCreateDynamicTexture(const FString& InBase64, const FString& Key) +{ + if (PreviewTextureCache.Contains(Key)) + { + UTexture2D* CacheTex = PreviewTextureCache[Key]; + if (IsValid(CacheTex)) return CacheTex; + } + + TArray DecodedBytes; + if (FBase64::Decode(InBase64, DecodedBytes)) + { + UTexture2D* Texture = FImageUtils::ImportBufferAsTexture2D(DecodedBytes); + if (Texture) + { + PreviewTextureCache.Add(Key, Texture); // 注入强引用容器,生命周期与 Subsystem 绑定,彻底拦截 GC 回收 + return Texture; + } + } + return nullptr; +} +``` + +在会话清理(如用户清空对话、新建会话或点击发送后),调用 `ClearTextureCache` 方法断开所有强引用反射指针: + +```cpp +void UUmgMcpActiveMessageSubsystem::ClearTextureCache() +{ + PreviewTextureCache.Empty(); // 失去强引用后,底层 UTexture2D 在下一个 GC Tick 会被自动安全释放,杜绝显存与物理内存泄露 +} +``` + +--- + +## 5. 结论 + +通过本文提出的自然对数亚线性压缩缩放算法,插件在对待发送图片预览与历史气泡的图文混排表现上展现出了无与伦比的自适应排版张力。结合反射堆强引用 GC 屏蔽层与编辑光标双向删除联动,整个系统在极端超高分辨率多图并发的测试场景下实现了零崩溃、零显存泄露、高排版还原度的高品质工业级体验。 diff --git a/Document/MaterialMcpProtocol.md b/Document/MaterialMcpProtocol.md new file mode 100644 index 0000000..1a86a65 --- /dev/null +++ b/Document/MaterialMcpProtocol.md @@ -0,0 +1,149 @@ +# Material MCP Protocol Draft + +本文记录当前开源 Material MCP 的精简协议原则。范围限定为 UE 5.8;不引入商业版服务依赖。 + +## 设计原则 + +1. 默认创建 UI 材质。`material_set_target` 和 `hlsl_set_target` 创建新材质时仍使用 `MD_UI` + `Translucent`,保证 UMG 场景只给名字也能看到结果。 +2. 非 UI 材质必须显式声明。使用 `hlsl_set_target` 的 `domain`、`blend_mode`、`shading_model`、`two_sided` 参数修改当前目标材质类型。 +3. HLSL 是主路径。Material ToolMode 默认只暴露 HLSL 闭环、显式类型修改和显式删除参数,避免 AI 走低阶图编辑。 +4. 读操作返回语义,不返回完整图。`hlsl_get` 返回 HLSL、参数快照和 `output_contract`,说明 `float4` 的 rgb/a 与额外 outputs 当前连接到什么材质输出。 +5. 写操作只做并集覆盖和追加。`hlsl_set` 可以更新代码、更新已有参数类型、追加新参数、追加/更新 outputs,但不能删除。 +6. 删除必须走单独命令。统一使用 `hlsl_delete(names, confirm_delete=true, kind?)`。默认按名称语义匹配 parameter/output;如果歧义,返回失败并要求补 `kind`。 + +## 当前精简工具 + +| Tool | 作用 | +| --- | --- | +| `hlsl_set_target(path, confirm_overwrite=false, create_if_not_found=true, domain?, blend_mode?, shading_model?, two_sided?)` | 设置或创建 HLSL 材质目标。新材质默认 UI;可携带类型字段切到非 UI。已有材质必须满足单 Custom 节点拓扑,否则需要确认覆写。 | +| `hlsl_get()` | 读取当前 HLSL、参数列表和输出契约。 | +| `hlsl_set(hlsl?, parameters?, outputs?)` | 并集式写入 HLSL、参数与材质输出。不会删除。 | +| `hlsl_delete(names, confirm_delete=true, kind?)` | 显式删除 HLSL 参数或输出。名称歧义时补 `kind="parameter"` 或 `kind="output"`。 | +| `hlsl_compile()` | 编译当前材质并返回精简诊断。 | + +## `hlsl_set_target` 类型参数 + +`domain` 支持: + +- `ui` +- `surface` +- `post_process` +- `deferred_decal` +- `light_function` +- `volume` + +`blend_mode` 支持: + +- `opaque` +- `masked` +- `translucent` +- `additive` +- `modulate` +- `alpha_composite` +- `alpha_holdout` + +`shading_model` 支持 UE 5.8 常用模型: + +- `unlit` +- `default_lit` +- `subsurface` +- `preintegrated_skin` +- `clear_coat` +- `subsurface_profile` +- `two_sided_foliage` +- `hair` +- `cloth` +- `eye` +- `single_layer_water` +- `thin_translucent` + +## 输出契约 + +HLSL Custom 节点主返回值固定为 `float4`。后端根据材质类型生成语义契约: + +```json +{ + "return": "float4", + "domain": "ui", + "blend_mode": "translucent", + "shading_model": "unlit", + "rgb_to": "EmissiveColor", + "a_to": "Opacity", + "outputs": [ + {"name": "Roughness", "target": "Roughness", "type": "float1", "connected": true} + ] +} +``` + +规则: + +- UI、Post Process、Light Function、Unlit 材质:`rgb -> EmissiveColor` +- 默认 Lit Surface:`rgb -> BaseColor` +- Masked:`a -> OpacityMask` +- 非 Opaque 且非 Masked:`a -> Opacity` +- Opaque:不声明 alpha 输出 + +`outputs` 是 Custom 节点的 AdditionalOutputs。HLSL 代码里使用同名 `inout` 变量赋值: + +```hlsl +Roughness = 0.35; +Metallic = 0.0; +Normal = normalize(float3(0, 0, 1)); +return float4(BaseColorValue, 1); +``` + +`outputs` 最简写法是字符串数组: + +```json +["Roughness", "Metallic", "Normal"] +``` + +需要自定义 HLSL 变量名或类型时使用对象: + +```json +[ + {"name": "ClearCoatAmount", "target": "CustomData0", "type": "float1"}, + {"name": "BentNormal", "target": "Normal", "type": "float3"} +] +``` + +常用 target 默认类型: + +- `BaseColor`, `EmissiveColor`, `Normal`, `Tangent`, `WorldPositionOffset`, `SubsurfaceColor`: `float3` +- `CustomizedUVs0` 到 `CustomizedUVs7`: `float2` +- `Metallic`, `Specular`, `Roughness`, `Anisotropy`, `Opacity`, `OpacityMask`, `AmbientOcclusion`, `Refraction`, `PixelDepthOffset`, `CustomData0`, `CustomData1`: `float1` + +## 非 UI 示例 + +创建一个可见的非 UMG Surface HLSL 材质: + +```python +await hlsl_set_target( + "/Game/Materials/M_HlslSurface", + domain="surface", + shading_model="unlit", + blend_mode="opaque" +) +await hlsl_set( + hlsl="Roughness = 0.25; return float4(0.1, 0.8, 1.0, 1.0);", + outputs=["Roughness"] +) +await hlsl_compile() +``` + +创建 Masked Surface: + +```python +await hlsl_set_target( + "/Game/Materials/M_HlslMasked", + domain="surface", + shading_model="unlit", + blend_mode="masked" +) +await hlsl_set(hlsl="return float4(1, 1, 1, UV.x > 0.5 ? 1 : 0);") +await hlsl_compile() +``` + +## 兼容层 + +传统 `material_*` 低阶图编辑工具保留为后端兼容层,但默认 MCP prompts 与 Material ToolMode 均隐藏这些工具。AI 应只看到并使用 HLSL 文本编辑闭环;需要图级调试时再由维护者显式开启兼容工具。 diff --git a/Document/SubtreeManagement.md b/Document/SubtreeManagement.md new file mode 100644 index 0000000..46e687e --- /dev/null +++ b/Document/SubtreeManagement.md @@ -0,0 +1,69 @@ +# Fab UMG MCP subtree management + +This repository is the Fab edition. It vendors three upstream projects and owns the closed Fab overlay. + +## Projects + +| Project | Remote | Branch | Local path | Rule | +| --- | --- | --- | --- | --- | +| Open-source UMG MCP | `upstream` | `main` | repository root / `Source/UmgMcp` | Pull from upstream. Do not push Fab code here. | +| Chat With Unreal | `chat-upstream` | `main` | `Source/ChatWithUnreal` | Manage with `git subtree`. | +| LiteRT-LM Unreal | `litert-upstream` | `master` | `Source/LiteRTLMUnreal` | Manage with `git subtree`. | +| Fab closed overlay | `origin` | `master` | `Source/UmgMcp/Public/FabServer`, `Source/UmgMcp/Private/FabServer` | Maintain only in this Fab repository. | + +## Ownership rule + +Maintain Fab-specific work only in: + +- `Source/UmgMcp/Public/FabServer` +- `Source/UmgMcp/Private/FabServer` +- `UmgMcp.uplugin` +- Fab export scripts, Codex install scripts, subtree-management scripts, and Fab-only documents + +Everything else should be treated as upstream-owned. If a Fab integration needs a change outside those paths, make it a small, explicit integration commit and expect to re-check it during every upstream merge. + +`UmgMcp.uplugin` is intentionally Fab-owned even though the open-source plugin also has a `.uplugin`. The Fab manifest declares the combined product modules (`UmgMcp`, `LiteRTLMUnreal`, `ChatWithUnreal`) and Fab marketplace metadata, so upstream merges should not overwrite it. + +## Common commands + +Run these from the repository root: + +```powershell +.\Tools\Subtree\Sync-Subtrees.ps1 -Action status +.\Tools\Subtree\Sync-Subtrees.ps1 -Action fetch +.\Tools\Subtree\Sync-Subtrees.ps1 -Action merge-umg +.\Tools\Subtree\Sync-Subtrees.ps1 -Action pull-chat +.\Tools\Subtree\Sync-Subtrees.ps1 -Action pull-litert +``` + +`merge-umg` defaults to `-UmgProtectMode current-diffs`. It protects every current Fab-side path that differs from `upstream/main`, except the separately managed `Source/ChatWithUnreal` and `Source/LiteRTLMUnreal` subtrees. Use `-UmgProtectMode fab-overlay` only when you intentionally want to protect the minimal Fab overlay list. + +For a full update: + +```powershell +.\Tools\Subtree\Sync-Subtrees.ps1 -Action sync-all +``` + +The script requires a clean working tree for merge/pull actions. This avoids mixing local Fab work with upstream subtree updates. Use `-AllowDirty` only when you have already reviewed the local changes. + +## Boundary check + +Before committing Fab-only work: + +```powershell +.\Tools\Subtree\Sync-Subtrees.ps1 -Action guard +``` + +If the guard reports files outside the Fab-owned boundary, either move the change to the correct upstream repository or document it as a Fab integration exception in the commit message. + +## Conflict policy + +When merging `upstream/main`, keep upstream changes for open-source files and keep Fab versions for Fab-owned files. In practice: + +- `Source/UmgMcp/Public/FabServer` and `Source/UmgMcp/Private/FabServer`: keep Fab. +- `UmgMcp.uplugin`: keep Fab, then manually port any genuinely required upstream descriptor changes. +- `Source/UmgMcp` outside `FabServer`: prefer upstream. +- Current Fab-side files that already differ from `upstream/main`: protected by default during `merge-umg`; review intentionally before allowing upstream to replace them. +- `Source/ChatWithUnreal` and `Source/LiteRTLMUnreal`: update only through `git subtree pull`. + +The helper script backs up the Fab overlay before `merge-umg` and restores it after a successful merge. Still review the diff before committing. diff --git a/Document/TaskBeginFlow.md b/Document/TaskBeginFlow.md new file mode 100644 index 0000000..6ae09d9 --- /dev/null +++ b/Document/TaskBeginFlow.md @@ -0,0 +1,31 @@ +# UmgMcp 任务流参数自决决议设计分析 + +依据 Winyunq 项目的战略核心原则,任务(Task)的分配与参数规整(如 `AssignedAgent` 与 `TargetAsset`)应当具备高度的灵活性与工程解耦。我们采用 **以 JSON 规则声明参数要求** 的动态验证机制,避免在 C++ 底座中写死任何业务判断。 + +## 流程图(Mermaid 结构表示) + +下面展示了在 `task_begin` 触发后,系统基于智能体自持的 JSON 参数模板进行校验并动态补全的核心流程: + +```mermaid +graph TD + A[大模型调用 task_begin] --> B[系统拉取发起者/接收者的 JSON 规则要求文件] + B --> C{检查要求的参数是否全部存在且不为空?} + + C -->|是: 满足规则| D[合并参数, 渲染 STaskBeginNode UI 卡片等待 Confirm] + C -->|否: 缺少关键参数| E[激活对应的 Global Agent 介入决议与自动补全] + + E --> E1[如: LayoutAgent 规则声明必须拥有 target_asset 参数] + E1 --> E2[缺少 target_asset 时, 触发 FileManageAgent 执行后台静默推理补全] + + E2 --> D +``` + +## 物理流程分析 + +1. **大模型调用工具**:大模型执行 `task_begin` 工具,这属于一个松散的参数传递阶段。 +2. **基于 JSON 模板的动态校验**: + * 每一个 `UmgMcpTaskAgent` 子类智能体都可以通过其 JSON 配置文件声明自身所需的要求参数。 + * 系统通过反射或规则遍历,动态比对当前 `PendingTask` 记录中的值是否完整且非空。 + * **例如:LayoutAgent 一定要求有一个非空的 `target_asset` 目标资产。** +3. **Global Agent 介入机制**: + * 如果校验发现参数缺失或不合规,则挂起流程,自动唤醒对应的全局后台辅助智能体(如全局资产管理 `FileManageAgent`),利用其后台物理推理来精准补全缺失参数。 diff --git a/Document/UmgWidgetMcpProtocol.md b/Document/UmgWidgetMcpProtocol.md new file mode 100644 index 0000000..e8431f5 --- /dev/null +++ b/Document/UmgWidgetMcpProtocol.md @@ -0,0 +1,68 @@ +# UMG Widget MCP Protocol Draft + +本文记录当前 UMG Widget MCP 的 Target、读、写、删除语义。范围限定为 UE 5.8。 + +## 设计原则 + +1. Target 是默认操作对象。`set_target_umg_asset` 决定当前 UMG 资产;`set_target_widget` 决定当前控件或容器。Widget Target 继承 UMG Target。 +2. 读操作返回语义。`get_widget_tree` 返回紧凑树;设置 Widget Target 后只读该子树。`query_widget_properties` 返回指定属性;`get_layout_data` 返回布局边界。 +3. 写操作只做并集覆盖、追加和重排。`create_widget` 只创建缺失控件;`set_widget_properties` 只覆盖传入属性,不删除未提及属性;`reorder_widget_tree` 只移动已存在的同父级控件顺序;`apply_layout` 应按 append/upsert 语义处理布局。 +4. 删除必须走单独命令。`delete_widget` 是显式删除工具,必须传入 `confirm_delete=true`。 +5. 默认 MCP 不暴露完整 JSON dump/apply 兼容路径。`export_umg_to_json` 和 `apply_json_to_umg` 保留为兼容/调试命令,默认 prompt 隐藏。 + +## 当前默认工具 + +| Tool | 作用 | +| --- | --- | +| `set_target_umg_asset(asset_path)` | 设置或创建当前 UMG Target。 | +| `set_target_widget(widget_name)` | 设置当前 Widget Target。 | +| `get_widget_tree()` | 读取当前 Widget Target 子树;无 Widget Target 时读取根树。 | +| `query_widget_properties(widget_name, properties)` | 读取指定控件属性。 | +| `get_layout_data(width?, height?)` | 读取布局边界。 | +| `create_widget(widget_type, new_widget_name, parent_name?)` | 创建控件;未给 parent 时使用 Widget Target 或根。 | +| `set_widget_properties(widget_name?, properties)` | 并集式设置属性;命令层支持缺省 widget_name 使用 Widget Target。 | +| `reorder_widget_tree(tree, root?)` | 并集式重排同父级控件顺序;未提及控件保持相对顺序,不创建不删除。 | +| `reparent_widget(widget_name?, new_parent_widget)` | 转换/重构控件层级;会保留子控件,无法保留时失败。 | +| `apply_layout(layout_content, widget_name?)` | 批量布局应用,作为默认高层布局入口。 | +| `delete_widget(widget_name, confirm_delete=true)` | 显式删除控件。 | +| `save_asset()` | 保存当前资产。 | + +## 写与删除 + +`set_widget_properties` 示例: + +```json +{ + "widget_name": "LoginCard", + "properties": { + "RenderOpacity": 0.95, + "Slot": { + "Padding": {"Left": 24, "Top": 16, "Right": 24, "Bottom": 16} + } + } +} +``` + +这只覆盖 `RenderOpacity` 和指定 Slot 字段,不会删除其他属性。 + +删除必须显式: + +```json +{ + "widget_name": "DebugButton", + "confirm_delete": true +} +``` + +未传 `confirm_delete=true` 时必须失败,并返回 Issue 15 风格错误。 + +## 隐藏兼容命令 + +以下命令不进入默认 MCP prompt 或 UMG ToolMode: + +- `check_widget_overlap` +- `export_umg_to_json` +- `apply_json_to_umg` +- `apply_html_to_umg` + +`check_widget_overlap` 是诊断工具;`export_umg_to_json` / `apply_json_to_umg` 是完整 JSON 兼容路径,容易让 AI 过度依赖全量快照或误判为替换式写入。默认流程应优先使用 Target 化的读写工具和 `apply_layout`。 diff --git a/Document/chat_dialogue.html b/Document/chat_dialogue.html new file mode 100644 index 0000000..95a97fe --- /dev/null +++ b/Document/chat_dialogue.html @@ -0,0 +1,265 @@ + + + + + + 2. How to Chat (4 Agent Modes) - UMG MCP + + + + + + + + + + + + + +
+ +
+
+ Official Docs + / + AI Chat & Interaction +
+
+
+

Active Agent State

+

C++ Subsystem Direct Connection

+
+
+
+ + +
+ +
+

+ + Chapter 2: How to Chat (4 Built-in Agent Modes) +

+

+ Inside the built-in UMG MCP chat panel on the right side of the Unreal Editor, AI communication is not a static one-size-fits-all session. Based on different development phases and contexts, this plugin categorizes AI chat states into four precise Agent modes: chat, develop, learning, and task at the C++ subsystem layer. +

+
+ + +
+

+ + 1. The 4 Agent Operational Logic & C++ Mechanisms +

+ +
+ +
+
+

+ + Chat Mode (Default Session Agent - FUmgMcpDefaultChatAgent) +

+ Chat +
+

+ Targeting: General context-aware conversations. Ideal for basic technical inquiries, design brainstorming, and conceptual clarification. +

+

+ C++ Mechanism: At the start of each query cycle, it triggers RestoreConversationContext(), pulling the complete substance of the previous conversation (historical JSON message snap) from local persistent session files. This historical sequence serves as the message context prefix submitted to the LLM provider, guaranteeing zero context fragmentation. +

+
+ + +
+
+

+ + Develop Mode (Dynamic Development Agent - FUmgMcpDevelopAgent) +

+ Develop +
+

+ Targeting: Highly context-sensitive UI authoring and widget editing. Focuses on high-precision UI layout adjustments and programmatic widget generation. +

+

+ C++ Mechanism: Upon interaction, it calls the unique DynamicallyUpdatePromptAndTools() method. It inspects the currently active UMG asset being edited in the Unreal Editor, dynamically re-synthesizes the session's System Instruction (system prompts), and filters permitted MCP tools based on the currently selected widget types. For instance, Canvas Slot adjustment tools are only exposed when CanvasPanel itself is selected, greatly narrowing the AI generation scope and boosting tool execution success rates. +

+
+ + +
+
+

+ + Learning Mode (Read-Only Perceptual Agent - FUmgMcpLearningAgent) +

+ Learning +
+

+ Targeting: Deep structural parsing, layout hierarchy perception, and step-by-step guidance on complex, pre-existing UMG widget structures. +

+

+ C++ Mechanism: The plugin loads the built-in learning.json tool configurations silently. During query evaluation, it executes ResolveTargetAndTreeContext() designed specifically for data optimization: it computes and compares the hash value of the current active viewport widget hierarchy. **Only** when you physically alter the layout structure does it bundle and upload the new tree representation to the context. Otherwise, it safely recycles the read-only cache, completely eliminating repetitive structural queries and saving huge token counts/network latency. +

+
+ + +
+
+

+ + Task Mode (Task Handover Agent - FUmgMcpTaskAgent) +

+ Task +
+

+ Targeting: Executing self-contained development tasks with strong consistency and comprehensive transactional safety boundaries. +

+

+ C++ Mechanism: The task handover flow runs under rigorous engineering controls. When the AI receives a special task_begin tool call, it fires AcceptTask(), saving your current editor focus path (e.g. `PreviousWidget`) into a private backup variable CapturedPreviousTarget. It then locks the editor viewport strictly onto the target task asset, masking any other asset modifications. Once the completion trigger task_end is issued, TaskEnd() executes, unlocking editing states and returning focus to the original active asset without any distortion. +

+
+
+
+ + +
+

+ + 🎨 Slate Chat UI Approval Queue & direct Memory execution +

+ +
+

+ Whenever an active Agent attempts an action that mutates your UMG assets (e.g., "create a button widget" or "delete a slot layout"), the plugin's underlying SUmgMcpMcpApprovalQueue (Slate Approval UI) interceptor activates. It presents an interactive, highlighted authorization card inside your chat timeline. +

+ +
+
💡 Operational Step-by-Step Experience:
+
    +
  1. Submit Query: You input a prompt, e.g. "Create a button widget named WinyunqButton under the Canvas panel".
  2. +
  3. AI Plan & Action Formulation: The Agent processes the request and silently queues the tool execution metadata card (such as create_widget) onto the Slate Chat view.
  4. +
  5. Approval Prompts: The interactive bubble displays a blue Accept and a gray Reject trigger button.
  6. +
  7. Zero Network Proxy Direct Connection: Clicking Accept routes the raw instruction directly to FFabServerHttpClient::ExecuteTool. It is instantly executed on Unreal's Game Thread in memory, refreshing the Slate Designer View and producing a real-time UMG object. There is no network loopback or roundtrip proxy!
  8. +
+
+
+
+ + +
+

📸 Screenshot Placeholder

+
+ +

[IMAGE_PLACEHOLDER: Unreal UMG MCP Built-in Chat Panel Window Layout]

+

Please take a screenshot of the UMG MCP chat window docked in the Unreal Editor, displaying the bottom Selector containing the chat/develop/learning/task modes.

+
+
+
+
+ + + + diff --git a/Document/chat_dialogue_zh.html b/Document/chat_dialogue_zh.html new file mode 100644 index 0000000..c3aa007 --- /dev/null +++ b/Document/chat_dialogue_zh.html @@ -0,0 +1,265 @@ + + + + + + 2. 怎么对话 (4种Agent) - UMG MCP + + + + + + + + + + + + + +
+ +
+
+ Official Docs + / + AI 对话交互 +
+
+
+

当前 Agent 模式活跃

+

C++ Subsystem 直连

+
+
+
+ + +
+ +
+

+ + 第二章:怎么对话(4 种内置 Agent 模式) +

+

+ 在虚幻编辑器右侧内置的 UMG MCP 对话面板中,AI 的对话并不是单一死板的。基于不同的场景与开发阶段,本插件在 C++ 底层划分了 chat, develop, learning, task 四种精密的 Agent 对话状态。 +

+
+ + +
+

+ + 1. 四大 Agent 运作机理与 C++ 机制 +

+ +
+ +
+
+

+ + Chat 模式 (默认会话 Agent - FUmgMcpDefaultChatAgent) +

+ Chat +
+

+ 定位: 通用的上下文感知对话,适合基础的技术交流、方案推演与概念澄清。 +

+

+ C++ 运转机理: 每次开始提问互动时,调用 RestoreConversationContext(),从当前的本地会话持久化存储中,完整拉取上一轮互动的 Substance(历史 JSON 消息快照),作为本轮提问的历史前缀提交至 LLM 供应商,保证上下文不丢失。 +

+
+ + +
+
+

+ + Develop 模式 (动态开发 Agent - FUmgMcpDevelopAgent) +

+ Develop +
+

+ 定位: 高情境感知的 UI 编写与修改模式,专注于高精度的 UI 操纵与控件生成。 +

+

+ C++ 运转机理: 在触发互动时,会调用独有的 DynamicallyUpdatePromptAndTools()。它检测虚幻编辑器当前正在编辑的活跃 UI 资产,动态重构当前会话的 System Instruction(系统提示词),并根据当前被激活选中的控件类型,动态过滤允许调用的 MCP 工具列表。例如,只选中 CanvasPanel 时才暴露出 Canvas Slot 相关的偏置调整工具,极大收窄了 AI 的生成边界,提高了工具调用的成功率。 +

+
+ + +
+
+

+ + Learning 模式 (只读感知 Agent - FUmgMcpLearningAgent) +

+ Learning +
+

+ 定位: 对复杂的已有 UMG 控件树进行只读式深度剖析、结构感知与教学引导。 +

+

+ C++ 运转机理: 插件会自动在后台加载内置的 learning.json 工具配置。在每次接收提问时,它调用 ResolveTargetAndTreeContext() 进行无冗余优化设计:实时计算并对比当前编辑器视口中控件树的 Hash 值。**只有**当您手动修改了 UI 导致 Hash 发生物理改变时,它才会将最新的树结构重新打包成上下文发送;若无修改,则继续复用之前的只读缓存,从物理上杜绝了对同一个 UMG 树进行重复网络查询带来的巨大 Token 开销与响应卡顿。 +

+
+ + +
+
+

+ + Task 模式 (任务接管 Agent - FUmgMcpTaskAgent) +

+ Task +
+

+ 定位: 执行有始有终的、具备强一致性与完整保护的安全独立开发任务包。 +

+

+ C++ 运转机理: 任务接管流的逻辑具备极高的工程严密性。当 AI 从会话中接收到特殊的 task_begin 工具调用时,触发 AcceptTask(),它会将您编辑器当前的活跃编辑资产路径(如 `PreviousWidget`)强制暂存至私有变量 CapturedPreviousTarget 中,并把当前任务专属的 UMG 资产强行推上舞台供 AI 独立编辑,在此期间物理屏蔽任何其他杂乱输入。直到接收到对应的终止命令 task_end 工具调用时,触发 TaskEnd(),释放资产锁定并完美的把您编辑器的编辑目标物归原主,物还原貌。 +

+
+
+
+ + +
+

+ + 🎨 内置 Chat UI 审批工作流 (Sslate/Slate 交互) +

+ +
+

+ 当内置 Agent 在对话中试图发起任何可能会修改您 UMG 资产的动作时(例如“创建一个按钮”或“删除一个布局”),插件底层的 SUmgMcpMcpApprovalQueue (审批队列) 控件就会立即在消息气泡中以高亮卡片的形式挂载。 +

+ +
+
💡 对话交互体验流程:
+
    +
  1. 发出提问:您在底栏输入:“在 Canvas 下帮我新建一个名为 WinyunqButton 的按钮”
  2. +
  3. AI 析出动作:内置 Agent 回复,并将工具执行动作(如 create_widget)以卡片形式静默投递到您的聊天时间轴中。
  4. +
  5. 呈现 Accept / Reject 按钮:气泡卡片底部呈现蓝色的 Accept (接受) 和灰色的 Reject (拒绝) 按钮。
  6. +
  7. 内存直连执行:当您点击 Accept 后,动作会绕过任何网络接口直接被投向 FFabServerHttpClient::ExecuteTool 并以极速内存直连的方式在虚幻主线程瞬间生成完毕,并在右侧视口立即刷新,给您极致丝滑的“手势化智造”开发体验!
  8. +
+
+
+
+ + +
+

📸 物理截图占位

+
+ +

[IMAGE_PLACEHOLDER: Unreal UMG MCP Built-in Chat Panel Window Layout]

+

请截图虚幻编辑器右侧停靠的 UMG MCP 对话面板窗口(包含底栏 Selector),以展示 chat/develop/learning/task 选择状态。

+
+
+
+
+ + + + diff --git a/Document/developer_manual.html b/Document/developer_manual.html new file mode 100644 index 0000000..2aa1fbc --- /dev/null +++ b/Document/developer_manual.html @@ -0,0 +1,228 @@ + + + + + + UMG MCP Advanced Interaction Manual + + + + + + + + + + + + + +
+ +
+
+ + Official Docs + + / + Quick Start +
+
+
+

Hardware Optimized

+

i9-13900HX | RTX 4060 | 64GB

+
+
+
+ + +
+
+
+
+ +
+

+ Empower AI to Design
+ + Unreal UMG UI via MCP + +

+

+ Welcome to the UMG MCP Advanced Interaction Manual! Designed specifically for Winyunq's ultimate engineering, this manual strips away the fluff to present exactly the 3 core pillars to get you building immediately. +

+
+
+
+ + v1.1.0-Win64 +
+
+
+ + + + + +
+
+

+ + 💡 Pro Tip: High Performance Dual-Loop Architecture +

+

+ This plugin features a high-performance Dual-Loop design. The built-in Chat UI communicates directly via fast memory-level C++ pointers to Subsystems (Zero latency). The TCP Port (55557) is exposed strictly as a secure loopback bridge for external AI agents like Claude Desktop or Cursor. Rest assured, your internal commands never take unnecessary loops through the network interface! +

+
+
+
+ + + + diff --git a/Document/developer_manual_zh.html b/Document/developer_manual_zh.html new file mode 100644 index 0000000..ee912a2 --- /dev/null +++ b/Document/developer_manual_zh.html @@ -0,0 +1,228 @@ + + + + + + UMG MCP 开发者高阶交互手册 + + + + + + + + + + + + + +
+ +
+
+ + Official Docs + + / + 快速开始 +
+
+
+

当前硬件配置已充分适配

+

i9-13900HX | RTX 4060 | 64GB

+
+
+
+ + +
+
+
+
+ +
+

+ 让 AI 通过 MCP 接口
+ + 完全掌控虚幻 UMG UI 制作 + +

+

+ 欢迎来到 UMG MCP 开发者高阶交互式手册!本手册专为 Winyunq 高标准开发打造,彻底抛弃无关的配置细节,直指三大核心板块,为您呈献极简、干货的开发与调试指引。 +

+
+
+
+ + v1.1.0-Win64 +
+
+
+ + + + + +
+
+

+ + 💡 开发者小贴士:双回路极速直连架构 +

+

+ 本插件内置了“双通路极度直连”架构。虚幻内置面板(Chat Panel)对话通过 C++ 内存指针瞬间连线 Subsystem,零端口延迟;外部端口 (TCP 55557) 仅作为开放接口,挂载至 Claude Desktop 或 Cursor 供外部开发调度使用。两者逻辑完美隔离,高聚无忧! +

+
+
+
+ + + + diff --git a/Document/index.html b/Document/index.html new file mode 100644 index 0000000..be9a66e --- /dev/null +++ b/Document/index.html @@ -0,0 +1,2253 @@ + + + + + + + + + + UMG MCP | AI-assisted Unreal UI production + + + + + + + + + +
+
+ + + +
+

Open-source UMG MCP project for Unreal Engine creators

+

Let AI build Unreal UIs while you stay the director.

+

UMG MCP connects AI assistants to Unreal Engine through MCP and FabServer, so they can edit UMG widgets, Blueprint logic, Sequencer animation, and HLSL UI materials under your approval.

+ +

Designed for local-first production: fewer wasted tokens, fewer blind edits, and more useful output per human decision.

+
+
+ +
+ +
+
+

Edition boundary / 版本边界

+

Open source gives the protocol. FabServer gives the finished editor product layer.

+

This documentation site is public because the UMG MCP protocol and tool surface are public. The Fab package is paid because it adds the private in-editor product layer: ChatWithUnreal, FabServer approval flow, provider setup, local LiteRT-LM, task agents, and production context handling.

+
+
+ + + + + + + + + + + + + + + + + + + + +
CapabilityOpen-source UMG MCPFab / FabServer package
Core Widget, Blueprint, Sequencer, Material, and HLSL MCP toolsIncludedIncluded
Python MCP server for external AI clientsIncluded, manual setupShares the same protocol; main product path is editor-first
Manual clone and source-level debuggingIncludedNot the primary workflow
Unreal Launcher / Fab installationNot includedIncluded
ChatWithUnreal in-editor chat panelNot includedIncluded
FabServer approval cards and direct in-memory executionNot includedIncluded
Agent modes: chat, develop, learning, taskNot includedIncluded
Provider settings UI: Google OAuth, API key providers, ZhipuAI, OpenAI-compatible endpointsNot includedIncluded
Local LiteRT-LM runtimeNot includedIncluded
Best buyer/user fitDevelopers and teams building custom MCP pipelinesArtists, technical artists, and production teams who want the complete editor experience
+
+
+ +
+
+

Product index

+

Find the part of UMG MCP that matches your job.

+

The plugin is easier to evaluate when it is separated into surfaces, agents, model providers, and editions. Use this index as the map.

+
+
+
+ +
+
+

Who it is for

+

A practical AI workflow for teams that ship UI.

+

UMG MCP is not a chatbot pasted beside Unreal. It is a production control layer for people who need repeatable assets, readable changes, and fast iteration inside the editor.

+
+
+
+ +
+
+

Core capability

+

One plugin, four creative surfaces.

+

The same AI conversation can move from widget structure to Blueprint behavior, then into animation timing and shader polish without leaving the Unreal project.

+
+
+
+ +
+
+

Agent system

+

A specialist agent stack, not one giant prompt.

+

FabServer breaks UI production into agents with narrower jobs. That keeps tool choices smaller, context cleaner, and human review easier.

+
+
+
+
+

How a complex UI request is divided

+

A Master Agent extracts the concept, a Layout Agent expands it into concrete UI regions, and specialized Widget, Material, Animation, and Blueprint agents finish the parts that need their tools. FileManage Agent can quietly resolve target assets when a task is missing a path.

+
+
+
+
+ +
+
+
+
+

MCP explained

+

MCP turns AI intent into structured editor actions.

+

The Model Context Protocol gives an AI client a typed list of tools. Instead of guessing how Unreal works, the model asks for exact actions such as reading the widget tree, creating a Button, setting an anchor, compiling Blueprint, or applying HLSL.

+

UMG MCP maps those tool calls into native C++ and Python routes for Unreal. The result is more reliable than screen scraping and more reviewable than asking AI to describe manual clicks.

+ + + Open MCP command index + +
+
+
+
+
+
+
+ +
+
+

FabServer advantage

+

The Fab version adds the production layer around MCP.

+

FabServer is the editor-side experience that makes MCP usable by real creators: agents, approvals, provider routing, local model support, task orchestration, context compression, and focused tool modes.

+
+
+ + + + +
+
+
+
+
+
UMG ToolMode
+
Material ToolMode
+
Animation ToolMode
+
Agent Stack
+
+
+ +
+
+

A day in Unreal

+

From prompt to asset without losing authorship.

+

The plugin is built around a reviewable loop: inspect, propose, approve, execute, save, and keep the context focused for the next step.

+
+
+
+ +
+
+

Product philosophy

+

We optimize AI for human energy efficiency.

+
+
+
+

The highest-efficiency engine in production is still the human.

+ UMG MCP is designed to amplify judgment, not bury it under endless automated output. +
+
+
+
+ +
+
+

Local-first AI

+

Small and local models become useful when the tools are precise.

+

A local model does not need to remember the whole editor. UMG MCP gives it focused tool schemas, active targets, cached prompts, and structured editor feedback.

+
+
+
+ +
+
+

Free and Pro

+

Open-source by belief, Pro by convenience and local safety.

+

Think of it like a Free / Go / Pro product ladder: the open-source edition remains the free protocol foundation, while the Fab edition is the Pro workflow for buyers who want less setup and safer local usage.

+
+
+
+ +
+
+

Open source and Fab

+

Choose the path that matches your project.

+

The open-source repository is the protocol testbed. The Fab edition packages the polished setup and production-oriented FabServer workflow for buyers who want less configuration and more delivery time.

+
+
+ + + +
+
+
+ +
+
+

Questions buyers ask

+

What to know before purchase.

+
+
+
+ +
+
+
+

Bring AI into Unreal where your assets actually live.

+

Use the open-source repository as the canonical project; choose the Fab package for marketplace installation, then connect your preferred AI provider: local LiteRT-LM, Google login, API keys, OpenAI-compatible gateways, ZhipuAI, or Codex CLI.

+
+ +
+
+
+ + + + + + diff --git a/Document/index_zh.html b/Document/index_zh.html new file mode 100644 index 0000000..710a5fb --- /dev/null +++ b/Document/index_zh.html @@ -0,0 +1,14 @@ + + + + + + + UMG MCP | 中文入口 + + + + +

进入 UMG MCP 中文页面

+ + diff --git a/Document/mcp_support.html b/Document/mcp_support.html new file mode 100644 index 0000000..6a19b1b --- /dev/null +++ b/Document/mcp_support.html @@ -0,0 +1,607 @@ + + + + + + 3. Supported MCPs (C++) - UMG MCP + + + + + + + + + + + + + +
+ +
+
+ Official Docs + / + Supported MCPs (C++) +
+
+
+

Subsystem Commands

+

7 C++ Open-Source Command Classes

+
+
+
+ + +
+ +
+

+ + Chapter 3: Supported MCP Interfaces (C++ Command Index) +

+

+ This guide focuses exclusively on the fully open-source, user-controlled C++ MCP commands (excluding the closed-source fabserver cloud components). Via direct calls through UUmgMcpBridge (C++ Bridge Subsystem), the AI can trigger and instantly execute native API tasks within Unreal's Game Thread across 7 core domains, enabling pin-level blueprint connection, widget spawning, and shader injection. +

+
+ + +
+ + +
+
+
+ +

1. Viewport & Graph Perception Commands (Attention)

+
+ FUmgMcpAttentionCommands +
+

+ Provides the AI with "visual focus" and logical positioning in the Unreal Editor's viewport and blueprint graphs. This is a prerequisite for executing any modifications. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Command TypeDescriptionCore Params (JSON)
get_last_edited_umg_assetRetrieves the path of the last modified UMG asset.None
get_recently_edited_umg_assetsLists UMG assets that were recently active in the editor.None
get_target_umg_assetQueries the active UMG asset currently locked in the Attention system.None
set_target_umg_assetLocks a specific UMG asset path as the AI's target for editing.{"asset_path": "String"}
get_target_widgetQueries the active selected widget name.None
set_target_widgetLocks onto a specific widget in the current active hierarchy.{"widget_name": "String"}
set_target_graphLocks onto a target graph or function. If pointing to Component.Event syntax (e.g. Button.OnClicked), it auto-wires and ensures the existence of the bound event.{"graph_name": "String"} or {"function_name": "String"}
get_target_graphRetrieves the active graph/function name.None
set_cursor_nodePositions the blueprint cursor (Program Counter) strictly on a designated node.{"node_id": "String"}
get_cursor_nodeRetrieves the current node ID the cursor is focused on.None
+
+
+ + +
+
+
+ +

2. UMG Widget Hierarchy & Slot Commands (Widget Operations)

+
+ FUmgMcpWidgetCommands +
+

+ Manages the underlying SWidget tree hierarchy in Unreal's memory, enabling high-fidelity layout creation and manipulation. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Command TypeDescriptionCore Params (JSON)
get_widget_treeReturns the entire widget nesting tree, showing parent-child hierarchy and slot types.None
query_widget_propertiesUses C++ Reflection to read all exposure fields and active parameters of a widget.{"widget_name": "String"}
get_widget_schemaQueries struct layouts, default slots, and supported parameters of a widget class.{"widget_class": "String"}
create_widgetConstructs a new widget of a specific class and hooks it into a parent widget's slot in memory.{"widget_name": "String", "widget_class": "String", "parent_name": "String"}
set_widget_propertiesUpdates reflection parameters batching colors, slots, sizes, alignment, and anchors.{"widget_name": "String", "properties": {"Property_Name": "Value"}}
delete_widgetPhysically deletes a widget and recursively destroys its nested children.{"widget_name": "String"}
reparent_widgetDetaches a widget and re-anchors it onto a new designated parent.{"widget_name": "String", "new_parent_name": "String"}
save_assetForces the editor to commit current memory adjustments to the UMG asset file.None
get_layout_dataFetches active size, boundary padding, offsets, and scales under viewport layout.None
check_widget_overlapPerforms geometric checks to analyze if two widgets collide or overlap in the layout coordinate space.{"widget_a": "String", "widget_b": "String"}
+
+
+ + +
+
+
+ +

3. UI Serialization & Sync Commands (File Sync)

+
+ FUmgMcpFileTransformationCommands +
+

+ Enables high-speed translation between the in-editor active UMG structures and physical JSON layout sheets on disk. +

+
+ + + + + + + + + + + + + + + + + + + + +
Command TypeDescriptionCore Params (JSON)
export_umg_to_jsonSerializes the active layout hierarchy and reflection properties to a file.{"export_path": "String"}
apply_json_to_umgParses a local JSON layout description and incremental rebuilds UMG asset parameters in the editor.{"json_path": "String"}
+
+
+ + +
+
+
+ +

4. UI Sequencer & Keyframe Commands (Sequencer)

+
+ FUmgMcpSequencerCommands +
+

+ Manages the editor's UI Sequencer tracks at the C++ level. AI can directly insert, modify, or erase keyframes from animation tracks to produce vibrant UI motion. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Command TypeDescriptionCore Params (JSON)
get_all_animationsLists all UI animations defined inside the current asset.None
create_animationInstantiates a brand new UWidgetAnimation object in the asset.{"animation_name": "String"}
delete_animationDeletes the specified animation object.{"animation_name": "String"}
set_property_keysInserts or overwrites keyframe values on a designated widget property animation channel at a precise time step.{"animation_name": "String", "widget_name": "String", "property_path": "String", "time": 0.5, "value": 1.0}
remove_property_trackDestroys a property animation channel associated with a widget.{"animation_name": "String", "widget_name": "String", "property_path": "String"}
get_animation_keyframesFetches the keyframe list and curves of the animation.{"animation_name": "String"}
get_animated_widgetsLists all widgets that possess active animation channels in the track.{"animation_name": "String"}
get_animation_full_dataExtracts an all-in-one comprehensive JSON packet outlining channels, properties, and times.{"animation_name": "String"}
animation_append_widget_tracksAppends blank property animation tracks to multiple widgets in batch.{"animation_name": "String", "widgets": ["String"]}
animation_delete_widget_keysClears a widget's keyframe data falling within a specified start and end time.{"animation_name": "String", "widget_name": "String", "start_time": 0.0, "end_time": 1.0}
+
+
+ + +
+
+
+ +

5. Blueprint Graph & Node Manipulation Commands (Blueprint)

+
+ FUmgMcpBlueprintCommands / manage_blueprint_graph +
+

+ This is the **flagship C++ engine capability**. The AI does not just construct layout widgets; it injects node steps directly in the Blueprint Editor, wiring execution flows and data values, and triggers fast recompilation! +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Command TypeSub-Action (subAction / action)Description & Intelligent C++ LogicCore Params (JSON)
manage_blueprint_graphcreate_node / add_nodeInjects a functional node in the graph. If coordinate is omitted, UUmgAttentionSubsystem calculates the cursor offset to avoid overlap. If autoConnectToNodeId is defined, it wires executing flow pins automatically.{"action": "create_node", "nodeType": "String", "x": 100, "y": 200, "autoConnectToNodeId": "String"}
delete_nodeDeletes a node from the graph. If the active cursor is focused on this node, the C++ subsystem relocates and shifts focus onto adjacent node pathways (newCursorNode).{"action": "delete_node", "nodeId": "String"}
connect_pinsWires execution (Exec) pins or data pins between two blueprint nodes.{"action": "connect_pins", "fromNode": "String", "fromPin": "String", "toNode": "String", "toPin": "String"}
add_variable / add_paramRegisters a new local variable or parameters in the blueprint metadata block.{"action": "add_variable", "varName": "String", "varType": "String"}
compile_blueprintNoneTriggers C++ physical compilation of the WidgetBlueprint, refreshing editor reflection tables and activating nodes immediately!None
create_blueprintNoneSpawns a generic blueprint class asset (e.g. Actor) in files.{"bp_name": "String", "parent_class": "String", "path": "String"}
add_component_to_blueprintNoneAppends root components or functional nodes (like Box, StaticMesh) to standard blueprints.{"bp_path": "String", "component_class": "String", "component_name": "String"}
+
+
+ + +
+
+
+ +

6. UI Material & HLSL Shader Injection Commands (Material & HLSL)

+
+ FUmgMcpMaterialCommands +
+

+ Tailored for premium motion graphic artists. The AI can parse active material structures and directly inject a localized HLSL shader script (e.g. frosted glass refraction, cyberpunk grid sweeping) inside custom material nodes, establishing correct pin parameters automatically. +

+
+
+ + C++ Router Matching Principle: +
+

+ Any JSON command payload whose Type field initiates with prefix material_ or hlsl_ is routed dynamically to the underlying C++ FUmgMcpMaterialCommands system for low-level shader generation and property alignment. +

+
+
+ + +
+
+
+ +

7. Editor World & Asset Pipeline Commands (Editor World & Assets)

+
+ FUmgMcpEditorCommands +
+

+ Enables speedy controls over level actors (static meshes, spotlight actors, camera rigs) and general file scanning pipelines in the Unreal Editor. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Command TypeDescriptionCore Params (JSON)
get_actors_in_levelLists all Actor instances currently resting in the active editor world.None
find_actors_by_nameFinds actors inside the 3D level matching full or partial names.{"actor_name": "String"}
spawn_actorSpawns meshes, lights, cameras, or custom blueprints into the level view.{"actor_class": "String", "location": {"x":0,"y":0,"z":0}}
delete_actorRemoves and destroys designated actor instances.{"actor_name": "String"}
set_actor_transformModifies active location, rotation, and scaling vectors of an actor in level.{"actor_name": "String", "location": {"x":0,"y":0,"z":0}}
refresh_asset_registryCommands the Asset Registry module to run a scan syncing new in-memory file changes.None
list_assetsQueries valid asset paths under specified directories.{"folder_path": "String"}
+
+
+ +
+ + +
+

+ + 💡 Dual-Loop Connection: Zero-Network Local In-Memory Bridge +

+

+ When deploying or interacting with UMG MCP, do not conflate external ports with internal routes. The C++ plugin utilizes a strict **Dual-Loop Physical Isolation** architecture: +

+
    +
  • + Built-in Direct Connection Loop (Zero Network Loops): When asking the built-in Agent directly inside the Unreal Editor panel and selecting Accept, commands are executed **100% in memory**. The panel communicates via direct C++ pointers with the subsystem, bypassing **any** loopback IP or socket layers. This delivers absolute local execution speeds and zero port leaks. +
  • +
  • + External Bridge Loop (TCP 55557 Port Listener): Only when exposing the editor control to external AI clients (like Claude Desktop or custom script nodes) does the C++ background thread initialize a socket listening on port TCP 55557 (configured default). It safely reads JSON packet blocks and feeds them back strictly under main thread locks. +
  • +
+
+ + +
+

📸 Architecture View Placeholder

+
+ +

[IMAGE_PLACEHOLDER: UmgMcp C++ Subsystem Dual-Loop Connection Architecture]

+

Provide a system topology rendering, visually showcasing the memory connection (zero loopback network overhead) of Slate Chat UI alongside the TCP 55557 external Python daemon bridging loop.

+
+
+
+
+ + + + diff --git a/Document/mcp_support_zh.html b/Document/mcp_support_zh.html new file mode 100644 index 0000000..43bfcef --- /dev/null +++ b/Document/mcp_support_zh.html @@ -0,0 +1,607 @@ + + + + + + 3. 支持哪些 MCP (C++) - UMG MCP + + + + + + + + + + + + + +
+ +
+
+ Official Docs + / + 支持哪些 MCP (C++) +
+
+
+

底层指令系统

+

7 大 C++ 开源 Command 类

+
+
+
+ + +
+ +
+

+ + 第三章:支持哪些 MCP 接口(开源部分 C++ 指令汇总) +

+

+ 本指南聚焦于除了闭源 fabserver 云端通信以外,完全开源、受您掌控的 C++ 底层 MCP 指令。通过 UUmgMcpBridge (C++ 桥接器 Subsystem) 直连,AI 可以直接发起并在虚幻引擎主线程中秒级执行下列 7 大领域 的数十种原生 C++ API,实现引脚级的蓝图连线、控件构造及材质注入。 +

+
+ + +
+ + +
+
+
+ +

1. Viewport & Graph 感知指令 (Attention)

+
+ FUmgMcpAttentionCommands +
+

+ 实现 AI 对虚幻编辑器视口和蓝图编辑状态的“视觉感知”与焦点锁定,是执行后续修改动作的前置条件。 +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
指令名称 (CommandType)功能描述核心参数 (JSON)
get_last_edited_umg_asset获取最后一次被修改编辑的 UMG 资产路径
get_recently_edited_umg_assets列表返回近期在编辑器中活跃的 UMG 资产集
get_target_umg_asset查询当前被 Attention 系统锁定的目标 UMG 资产
set_target_umg_asset强制将指定 UMG 资产锁定为当前 AI 操纵目标{"asset_path": "String"}
get_target_widget查询当前选中的目标控件名称
set_target_widget设置当前 AI 聚焦的 UMG 控件{"widget_name": "String"}
set_target_graph设置当前编辑的目标蓝图图表或函数,若目标为 Component.Event(如 Button.OnClicked)将调用 C++ 自动生成对应的绑定事件{"graph_name": "String"} 或 {"function_name": "String"}
get_target_graph获取当前操作的蓝图图表名称
set_cursor_node将当前逻辑编辑焦点定位在图表中指定节点{"node_id": "String"}
get_cursor_node获取当前逻辑光标指向的节点 ID
+
+
+ + +
+
+
+ +

2. UMG 控件架构指令 (Widget Operations)

+
+ FUmgMcpWidgetCommands +
+

+ 直接操纵虚幻 UMG 编辑器底层的 SWidget 控件树,进行高精度的层级增删改查。 +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
指令名称 (CommandType)功能描述核心参数 (JSON)
get_widget_tree获取完整 UMG 控件树层级结构,包括父子嵌套及槽类型
query_widget_properties利用 C++ 反射(Reflection)查询指定控件的所有可编辑属性值{"widget_name": "String"}
get_widget_schema获取指定控件的基类结构和支持的布局元数据{"widget_class": "String"}
create_widget在指定父控件和 Slot(插槽)下,物理创建一个全新的控件对象{"widget_name": "String", "widget_class": "String", "parent_name": "String"}
set_widget_properties批量或单独更新指定控件的反射属性值(支持 Slot、颜色、锚点等){"widget_name": "String", "properties": {"Property_Name": "Value"}}
delete_widget物理销毁一个控件以及它下面的所有子层级树{"widget_name": "String"}
reparent_widget重新调整控件在控件树中的嵌套层级(换亲){"widget_name": "String", "new_parent_name": "String"}
save_asset强制命令虚幻编辑器将当前的 UMG 物理资产保存落盘
get_layout_data读取当前编辑器视口下的物理尺寸、外边距及偏移布局数据
check_widget_overlap根据布局槽的物理参数,分析指定的两个控件在视口中是否碰撞或重叠{"widget_a": "String", "widget_b": "String"}
+
+
+ + +
+
+
+ +

3. UI 物理文件序列化指令 (File Transformation)

+
+ FUmgMcpFileTransformationCommands +
+

+ 提供将 UMG 控件物理状态与磁盘通用 JSON 文件进行高阶转换的序列化引擎。 +

+
+ + + + + + + + + + + + + + + + + + + + +
指令名称 (CommandType)功能描述核心参数 (JSON)
export_umg_to_json将当前 UMG 控件的全部树关系与反射属性完整序列化并物理输出为标准 JSON 格式{"export_path": "String"}
apply_json_to_umg读取外部 JSON 布局描述文件,利用增量反序列化技术,在编辑器中物理重建或修改 UMG 资产{"json_path": "String"}
+
+
+ + +
+
+
+ +

4. UI Sequencer 动效与关键帧指令 (Sequencer)

+
+ FUmgMcpSequencerCommands +
+

+ 直接在 C++ 层面操纵 UI 的 Sequencer (动画轨道),向控件中精准植入、编辑或清理关键帧,实现灵动特效。 +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
指令名称 (CommandType)功能描述核心参数 (JSON)
get_all_animations拉取当前 UMG 资产内所有的 UI 动效名列表
create_animation物理创建一个全新的 UWidgetAnimation 动画对象{"animation_name": "String"}
delete_animation删除指定的 UWidgetAnimation 动画对象{"animation_name": "String"}
set_property_keys在特定的时间切片上,为控件的某个动画属性强行写入或覆写关键帧数据值{"animation_name": "String", "widget_name": "String", "property_path": "String", "time": 0.5, "value": 1.0}
remove_property_track物理移除指定控件在某个动画下的特定属性渲染轨道{"animation_name": "String", "widget_name": "String", "property_path": "String"}
get_animation_keyframes返回动画的全部关键帧时间轴排布数据{"animation_name": "String"}
get_animated_widgets查询当前动画绑定控制了哪些控件节点{"animation_name": "String"}
get_animation_full_data一键打包返回动画下的所有轨道、通道及关键帧的超完整 JSON 结构{"animation_name": "String"}
animation_append_widget_tracks批量为多个控件追加空的动效轨道{"animation_name": "String", "widgets": ["String"]}
animation_delete_widget_keys清理特定时间段内某个控件在动画中的所有关键帧{"animation_name": "String", "widget_name": "String", "start_time": 0.0, "end_time": 1.0}
+
+
+ + +
+
+
+ +

5. 蓝图低阶图表连线与高阶逻辑指令 (Blueprint Graph & Action)

+
+ FUmgMcpBlueprintCommands / manage_blueprint_graph +
+

+ 这是本插件最强悍的黄金级 C++ 能力。AI 通过它不仅能生成控件,还能在蓝图图表中生成逻辑节点,控制光标在节点间自动流转并自动引脚连线(Execution Pin / Variable Pin Wiring),且支持快捷编译! +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
指令名称 (CommandType)子动作 (subAction / action)功能与 C++ 智能逻辑描述核心参数 (JSON)
manage_blueprint_graphcreate_node / add_node在蓝图图表中注入一个节点。若未指定坐标将调用 UUmgAttentionSubsystem 自动计算非重叠偏置;若指定 autoConnectToNodeId,将自动拉出引脚与目标节点进行顺畅连线。{"action": "create_node", "nodeType": "String", "x": 100, "y": 200, "autoConnectToNodeId": "String"}
delete_node从图表中物理擦除一个节点。若删除的正是光标所在节点,C++ 系统会自动寻找前驱或后继节点,重设光标焦点(newCursorNode)。{"action": "delete_node", "nodeId": "String"}
connect_pins在图表中进行引脚级(Pin-to-Pin)硬连线,支持执行流连线与参数值连线。{"action": "connect_pins", "fromNode": "String", "fromPin": "String", "toNode": "String", "toPin": "String"}
add_variable / add_param在蓝图中动态声明并注册一个新变量或输入输出参数。{"action": "add_variable", "varName": "String", "varType": "String"}
compile_blueprint物理编译当前的 WidgetBlueprint,实时刷新编辑器反射缓存,令前述连线与变量当场生效!
create_blueprint物理创建普通的 Actor 蓝图类资产{"bp_name": "String", "parent_class": "String", "path": "String"}
add_component_to_blueprint为通用蓝图注入根组件或子组件(如 Box/StaticMesh 等){"bp_path": "String", "component_class": "String", "component_name": "String"}
+
+
+ + +
+
+
+ +

6. UI 材质与 HLSL 着色器指令 (Material & HLSL)

+
+ FUmgMcpMaterialCommands +
+

+ 这是专为 UE 高级动效开发者设计的着色器工具集。AI 能够解析现有 UI 材质的结构树,或者在指定材质节点中直接注入一段定制的 HLSL 局部渲染算法(例如霓虹扫描、毛玻璃折射算法),物理自动生成节点并连入主输出引脚。 +

+
+
+ + C++ 匹配规则特性: +
+

+ 所有在 C++ 派发器中以 material_ 开头或以 hlsl_ 开头的 JSON 指令,都会自动被路由至底层的 FUmgMcpMaterialCommands 进行高级解析与编译。支持如材质参数修改、节点连接、着色器片段自动对齐等高阶特效开发需求。 +

+
+
+ + +
+
+
+ +

7. 关卡世界与通用资产管理指令 (Editor World & Assets)

+
+ FUmgMcpEditorCommands +
+

+ 用于对关卡(Level)中的静态网格体、灯光及相机等 3D 元素进行快捷操纵,并提供全局资产扫描和状态检索。 +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
指令名称 (CommandType)功能描述核心参数 (JSON)
get_actors_in_level列表返回当前关卡世界中的全部 Actor 及其类型
find_actors_by_name通过模糊匹配名称,在关卡中查找特定实例{"actor_name": "String"}
spawn_actor在关卡世界的指定位置生成一个标准网格体、灯光、相机或自定义类{"actor_class": "String", "location": {"x":0,"y":0,"z":0}}
delete_actor从 3D 视口中删除指定的 Actor{"actor_name": "String"}
set_actor_transform更新 Actor 的三维平移、旋转与缩放参数{"actor_name": "String", "location": {"x":0,"y":0,"z":0}}
refresh_asset_registry强制命令编辑器资产注册表进行全量或局部同步扫描,确保新生成资产被 AI 发现
list_assets查询指定路径或通配符下的所有可用资产目录{"folder_path": "String"}
+
+
+ +
+ + +
+

+ + 💡 真正的“双回路”无网络代理内存直连 +

+

+ 在开发或查阅文档时,切勿混淆概念。UMG MCP 插件在系统架构上拥有精密的 双回路物理隔离 设计: +

+
    +
  • + 内置直接直连回路(零网络):当您直接在编辑器右侧的 UMG MCP 对话面板中向 Agent 提问并点击 Accept 审批时,前述指令是 100% 内存级直连 执行的。它直接调用 C++ 底层指针派发,绝对不通过 任何网络端口或回环 IP,不存在网络代理延时,具有极致的绝对安全与性能! +
  • +
  • + 外部桥接回路(TCP 55557 监听):仅当您需要用外部的 AI 工具(例如 Claude Desktop 或您自己的外部 Python 代理进程)来接管虚幻时,插件的底层后台才会在子线程启动一个轻量级套接字监听端口(默认 TCP 55557)。它仅供外部 AI 读写 JSON 指令进行虚幻引擎的同步遥控。两者物理隔离,安全无虞。 +
  • +
+
+ + +
+

📸 物理架构视图占位

+
+ +

[IMAGE_PLACEHOLDER: UmgMcp C++ Subsystem Dual-Loop Connection Architecture]

+

这里可绘制一张架构拓扑图,展示内部 Slate/Subsystem 内存直连(零网络环回)与外部 Python TCP 55557 遥控的物理隔离双回路机制。

+
+
+
+
+ + + + diff --git a/Document/model_config.html b/Document/model_config.html new file mode 100644 index 0000000..1e8edcf --- /dev/null +++ b/Document/model_config.html @@ -0,0 +1,284 @@ + + + + + + 1. Model Configuration - UMG MCP + + + + + + + + + + + + + +
+ +
+
+ Official Docs + / + Model Config +
+
+
+

Hardware Status

+

i9-13900HX | RTX 4060 | 64GB

+
+
+
+ + +
+ +
+

+ + Chapter 1: Model Configuration (Four Parallel Modes) +

+

+ To enable seamless UI creation for AI, UMG MCP features four parallel model access mechanisms. Developers can configure their preferred settings within the Unreal Editor at Project Settings -> Unreal Motion Graphics MCP. +

+
+ + +
+

+ + 1. Four Parallel Modes in Detail +

+ +
+ +
+
+

+ 01 + Local Model (LiteRT-LM) +

+ Offline / Built-in +
+

+ How it works: Setting bEnableLiteRtLm = true fires up the built-in C++ LiteRT inference engine inside the editor process. It directly loads local model files (e.g., gemma-4-E2B-it.litertlm) placed in the plugin's Resources/Models directory. +

+
+

🛠️ Winyunq Hardware Optimization Advice:

+

To fully leverage your i9-13900HX CPU and RTX 4060 GPU:

+
    +
  • Configure LocalModelContextLength (Context Length) to 65536.
  • +
  • Set LocalModelPrefillChunkSize to 4096 to utilize the parallel execution capabilities of the RTX 4060.
  • +
+
+
+ + +
+
+

+ 02 + Google Account Login (AuthLogin) +

+ OAuth 2.0 +
+

+ How it works: Selecting this launches a secure Google OAuth 2.0 flow managed by UUmgMcpAuthenticationSubsystem. The plugin handles access token retrieval automatically to query Gemini API endpoints without asking developers for manual API keys. +

+
+ + +
+
+

+ 03 + API Key Configuration (ApiKey) +

+ Custom Preset +
+

+ How it works: Configure API credentials for multiple remote model providers. The system ships with presets for Google (Gemini API) and ZhipuAI, alongside a fully customizable Custom preset supporting any OpenAI-compatible endpoints (e.g. DeepSeek, local LM-Studio, or OneAPI gateways). +

+
+ + +
+
+

+ 04 + Local Command Line (Local CLI) +

+ Pipe Direct +
+

+ How it works: Made for automation engineers. Set your primary provider to CLI and fill in the executable command in LocalCliCommand. The plugin launches the console process in the background and pipes conversation payloads via standard I/O (StdIn/StdOut) for low-level execution control. +

+
+
+
+ + +
+

+ + 🔐 API Key Protection & Non-Git Persistence Architecture +

+ +
+
+ +

+ In collaborative engineering, a catastrophic mistake is checking sensitive API keys into public Git repositories. To eliminate this vulnerability, UMG MCP leverages Unreal Engine's config architecture to ensure absolute credential isolation: +

+ +
+
+
+ +
+
+
UI Obfuscation via meta=(Password=true)
+

+ Inside `UmgMcpSettings.h`, the API Key properties are annotated with meta=(Password=true). Unreal's Details panel automatically converts the plain text field into masked dots, shielding it from screensharing or video recordings. +

+
+
+ +
+
+ +
+
+
Out-of-Git Storage: Saved/Config/WindowsEditor/Editor.ini
+

+ Although the settings class is declared as UCLASS(Config = Editor, DefaultConfig), all API Key fields are persisted through runtime-only UPROPERTY(Config) macros. This means: +

+
    +
  • Entering and saving keys inside the editor **never** writes credentials to Config/DefaultEditor.ini (which is tracked by Git).
  • +
  • Instead, keys are saved in your local workspace cache at Saved/Config/WindowsEditor/Editor.ini.
  • +
  • Under standard Unreal project layouts, the entire Saved/ folder is **strictly ignored** in the project's .gitignore file. Your keys never leave your machine!
  • +
+
+
+
+
+
+ + +
+

📸 Screenshot Slot (Click to expand)

+
+ +

[IMAGE_PLACEHOLDER: Unreal Settings - DeveloperSettings Tab for Unreal Motion Graphics MCP]

+

Launch Unreal, head to Project Settings, screenshot the "Unreal Motion Graphics MCP" fields, and replace this placeholder card.

+
+
+
+
+ + + + diff --git a/Document/model_config_zh.html b/Document/model_config_zh.html new file mode 100644 index 0000000..833732d --- /dev/null +++ b/Document/model_config_zh.html @@ -0,0 +1,284 @@ + + + + + + 1. 模型配置指南 - UMG MCP + + + + + + + + + + + + + +
+ +
+
+ Official Docs + / + 模型配置 +
+
+
+

硬件状态

+

i9-13900HX | RTX 4060 | 64GB

+
+
+
+ + +
+ +
+

+ + 第一章:怎么配置模型(平行四选一) +

+

+ 在 UMG MCP 中,为了让 AI 完美编织 UI,我们设计了四种平行的模型接入机制。您可以根据开发者的实际部署情况(如本地计算或远程 API),在虚幻编辑器的 Project Settings -> Unreal Motion Graphics MCP 中进行一键配置。 +

+
+ + +
+

+ + 1. 四大平行配置模式详解 +

+ +
+ +
+
+

+ 01 + 本地大模型 (LiteRT-LM) +

+ 内置免梯 +
+

+ 运作原理: 开启此选项(设置 bEnableLiteRtLm = true)后,插件将直接拉起内置的 C++ LiteRT 推理引擎。它直接加载保存在插件 Resources/Models 目录下的本地模型文件(例如 gemma-4-E2B-it.litertlm)。 +

+
+

🛠️ Winyunq 硬件调优建议:

+

得益于您强大的 i9-13900HX CPURTX 4060 GPU 硬件:

+
    +
  • 建议将 LocalModelContextLength(上下文长度)设为 65536
  • +
  • LocalModelPrefillChunkSize 设为 4096,以发挥 RTX 4060 大吞吐并行的优势,保障流畅的生成体验。
  • +
+
+
+ + +
+
+

+ 02 + Google 登录账号 (AuthLogin) +

+ 一键云连 +
+

+ 运作原理: 选择此供应商后,通过虚幻内置的 UUmgMcpAuthenticationSubsystem 调起 Google OAuth 2.0 登录流程,完成账号安全授权。插件将直接通过网络请求获取临时的 Access Token 进行鉴权,无缝直连 Google Gemini API,免去手动输入 API Key 的琐碎流程。 +

+
+ + +
+
+

+ 03 + API 密钥配置 (ApiKey) +

+ 高阶自定义 +
+

+ 运作原理: 支持配置多组远程大模型平台。系统自带 Google (Gemini API)、ZhipuAI (智谱 AI) 预设,并支持 Custom 模式(可填入任意符合 OpenAI 协议的自定义 Endpoint,如 DeepSeek、本地 OneAPI/LM-Studio 后端)。支持模型配置的多 Tag 调度路由。 +

+
+ + +
+
+

+ 04 + 本地命令行 (Local CLI) +

+ 管道直通 +
+

+ 运作原理: 专为极致的脚本极客设计。设置首选供应商为 CLI 模式,并在 LocalCliCommand 中配置可执行文件名。插件在推进会话时,将在后台启动此控制台进程,以标准输入输出 (StdIn/StdOut) 的管道方式接收和回传大模型数据,实现最底层的完全控制。 +

+
+
+
+ + +
+

+ + 🔐 API Key 安全防护与非 Git 持久化原理 +

+ +
+
+ +

+ 在团队协作中,最常见的灾难就是**误将包含个人或公司付费 API Key 的配置文件提交到公共 Git 仓库**,导致巨额账单泄露。为此,UMG MCP 插件在底层完美结合了虚幻引擎的安全特性,设计了物理隔离的双重防泄露机制: +

+ +
+
+
+ +
+
+
属性脱敏:meta=(Password=true)
+

+ 在 `UmgMcpSettings.h` 源码中,API 密钥定义为 meta=(Password=true)。这使得虚幻编辑器在 Details 面板展示此属性时,会自动对其执行密码圆点脱敏遮罩,防窥防屏录。 +

+
+
+ +
+
+ +
+
+
非 Git 持久化路径:Saved/Config/WindowsEditor/Editor.ini
+

+ 该配置类声明为 UCLASS(Config = Editor, DefaultConfig),但所有的 API Key 数据均存放在由 UPROPERTY(Config) 修饰的运行时字段中。这表明: +

+
    +
  • 当您在编辑器中输入并保存配置时,它**绝不**会写入项目的 Config/DefaultEditor.ini(该文件通常需要提交至 Git 跟踪);
  • +
  • 而是自动持久化在项目根目录下的 Saved/Config/WindowsEditor/Editor.ini 本地缓存中。
  • +
  • 根据虚幻的工业标准,整个 Saved/ 目录在 Git 的 .gitignore 中是**默认且强制物理屏蔽**的!
  • +
+
+
+
+
+
+ + +
+

📸 物理截图占位(双击此卡片查看截图详情)

+
+ +

[IMAGE_PLACEHOLDER: Unreal Settings - DeveloperSettings Tab for Unreal Motion Graphics MCP]

+

请运行虚幻编辑器,打开项目设置,截图“Unreal Motion Graphics MCP”属性窗口并替换此占位。

+
+
+
+
+ + + + diff --git a/README-website.md b/README-website.md new file mode 100644 index 0000000..1d07855 --- /dev/null +++ b/README-website.md @@ -0,0 +1,138 @@ +# UMG MCP Website — Deployment Guide + +This document explains the website structure and how to deploy it. + +## File Structure + +``` +/ +├── index.html # Hero landing page +├── open-source.html # Open source version page +├── commercial.html # Commercial Fab version page +├── features.html # Features & comparison table +├── architecture.html # Technical architecture & SVG diagrams +├── workflow.html # Workflow & process diagrams +├── roadmap.html # Development roadmap timeline +├── getting-started.html # Quick start guide (tabbed: OSS + Commercial) +├── contact.html # Contact & support page +├── README-website.md # This file +│ +└── assets/ + ├── css/ + │ └── main.css # Main stylesheet (dark tech theme) + ├── js/ + │ └── main.js # i18n, nav, animations, interactions + └── i18n/ + ├── en.json # English translations + └── zh.json # Chinese (Simplified) translations +``` + +## Technology Stack + +- **Pure HTML/CSS/JS** — no build tools, no frameworks +- **Vanilla JS** — no React/Vue/jQuery +- **CSS Custom Properties** — theming via CSS variables +- **IntersectionObserver** — scroll-triggered animations +- **JSON i18n** — client-side language switching +- **Inline SVG** — architecture and flow diagrams + +## Local Development + +Simply open any HTML file in a browser. For best results (especially i18n fetch), serve with a local HTTP server: + +```bash +# Python +python -m http.server 8080 + +# Node.js +npx serve . + +# VS Code +# Install "Live Server" extension, right-click index.html → Open with Live Server +``` + +Then visit: http://localhost:8080 + +## GitHub Pages Deployment + +1. Push the repository to GitHub +2. Go to **Settings → Pages** +3. Set source to **Deploy from a branch** +4. Select `main` branch, `/ (root)` folder +5. Click **Save** + +The site will be available at: `https://.github.io//` + +> All paths use relative URLs so the site works at any base path. + +## i18n System + +Language switching works via: + +1. `data-i18n="key"` attributes on HTML elements +2. `assets/i18n/en.json` and `assets/i18n/zh.json` translation files +3. `I18n.setLang('zh')` / `I18n.setLang('en')` in JS + +**Default language**: Detected from `navigator.language`. Falls back to Chinese (`zh`) if not English. + +**Persistence**: Language preference is saved to `localStorage` under key `umgmcp_lang`. + +**Adding translations**: +1. Add the key/value to both `en.json` and `zh.json` +2. Add `data-i18n="your.key"` to the HTML element + +## Navigation & Footer + +Navigation and footer are rendered by JavaScript (`renderNav()` and `renderFooter()` in `main.js`). Each page only needs: + +```html + + +
+ +``` + +The active nav link is automatically determined from `window.location.pathname`. + +## Animations + +| Animation | Trigger | Implementation | +|-----------|---------|----------------| +| Hero typing | Page load | JS interval loop | +| Particle field | Page load | JS DOM generation | +| Card reveal | Scroll into view | IntersectionObserver + `.reveal` class | +| Counter | Scroll into view | IntersectionObserver + `data-counter` | +| SVG flow lines | Scroll into view | IntersectionObserver + CSS stroke-dashoffset | +| Glow card | Mouse move | CSS custom property `--mx`/`--my` | +| FAQ accordion | Click | CSS max-height transition | +| Tab switch | Click | CSS display + fadeIn animation | + +## Customization + +### Colors +Edit CSS variables in `assets/css/main.css`: +```css +:root { + --primary: #7c3aed; /* purple */ + --secondary: #2563eb; /* blue */ + --accent: #06b6d4; /* cyan */ + /* ... */ +} +``` + +### Adding a new page +1. Create `new-page.html` at root +2. Include standard head/nav/footer: +```html + + +
+ +``` +3. Add to the `pages` array in `renderNav()` in `main.js` +4. Add translation keys to both JSON files + +## Links + +- **GitHub**: https://github.com/winyunq/UnrealMotionGraphicsMCP +- **Fab Marketplace**: https://www.fab.com/zh-cn/listings/f70dbcb0-11e4-46bf-b3f7-9f30ba2c9b71 diff --git a/Readme.md b/Readme.md index 0742d72..fab2666 100644 --- a/Readme.md +++ b/Readme.md @@ -1,102 +1,211 @@ -[中文版点击这里](Readme_zh.md) +[中文版](Readme_zh.md) + +
+

UnrealMotionGraphicsMCP

+

Open-source MCP tools for AI-assisted Unreal Engine UMG authoring.

+

+ Web Manual + · Quick Start + · Protocol Reference + · Issues + · Discord +

+

+ License MIT + Unreal Engine 5.8 + Platform Win64 + AgentSeal MCP +

+
-# UE5-UMG-MCP 🤖📄 +--- -**A Version-Controlled AI-Assisted UMG Workflow** +**UnrealMotionGraphicsMCP** makes Unreal UMG editing accessible to AI agents through explicit, versionable MCP commands. Instead of asking an agent to guess from screenshots or click through the editor, this plugin exposes the real editor state: widget trees, slot properties, Blueprint graph operations, UI materials, animation tracks, and JSON round-trips. -![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)![Status: Experimental](https://img.shields.io/badge/status-experimental-red.svg)![Built with AI](https://img.shields.io/badge/Built%20with-AI%20Assistance-blueviolet.svg)[![AgentSeal MCP](https://agentseal.org/api/v1/mcp/https-githubcom-winyunq-unrealmotiongraphicsmcp/badge)](https://agentseal.org/mcp/https-githubcom-winyunq-unrealmotiongraphicsmcp) +The open-source plugin is the protocol and editor bridge. It is meant to be readable, debuggable, and useful for research, custom pipelines, issue reports, and community fixes. -[Demo Designed A RTS UI](https://youtu.be/O86VCzxyF5o) +## What This Project Does -[Demo Recreating the UE5 editor](https://youtu.be/h_J70I0m4Ls) +| Area | Open-source capability | +| --- | --- | +| UMG widgets | Create widgets, inspect trees, set properties and slots, reorder children, replace subtrees, export and apply JSON | +| Blueprint / BlueCode | Create graph nodes, wire pins, bind widget references, and apply compact code-like graph statements | +| Materials | Create UI materials, set parameters, add supported expressions, and test HLSL-oriented material workflows | +| Animation | Create UMG animation tracks and keyframes for render transform, opacity, color, and timing | +| Editor bridge | Let external MCP clients call Unreal Editor through a local loopback bridge on `127.0.0.1:55557` | -[Demo Recreating the UE5 editor in UMG editor](https://youtu.be/pq12x2MH1L4) +## Edition Boundary -[Chat with Gemini 3 to editor the UMG file](https://youtu.be/93_Fiil9nd8) +There is one public UMG MCP project, and two practical ways to use it: ---- +- **Open-source edition**: the public protocol, Unreal editor bridge, Python MCP server, tool schemas, tests, and protocol documents. +- **Fab / FabServer edition**: the private packaged product layer for users who want the in-editor chat product, provider setup UI, approval workflow, local model integration, and less manual installation. -### 🛍️ Looking for an easier Setup? Try the Fab Version! +| Capability | Open-source edition | Fab / FabServer edition | +| --- | --- | --- | +| Core UMG widget MCP tools | Yes | Yes | +| Widget tree readback, property edits, layout append/upsert, JSON export/import | Yes | Yes | +| Blueprint / BlueCode protocol direction and node-level bridge | Yes | Yes | +| Sequencer / UMG animation tools | Yes | Yes | +| Material and HLSL workflow | Yes | Yes | +| Python MCP server for external clients | Yes, manual setup through `Resources/Python` | Packaged users can still rely on the shared protocol, but the product workflow is editor-first | +| Manual clone/build workflow | Yes | No, installed through Fab / Unreal Launcher flow | +| In-editor ChatWithUnreal panel | No | Yes | +| FabServer approval queue and direct in-memory execution | No | Yes | +| Built-in agent modes such as chat, develop, learning, and task | No | Yes | +| Model provider settings UI: Google OAuth, API keys, ZhipuAI, OpenAI-compatible endpoints | No | Yes | +| Local LiteRT-LM integration | No | Yes | +| Context compression / production conversation management | No | Yes | +| Best fit | Developers, researchers, contributors, custom MCP pipelines | Artists, technical artists, and production teams who want the finished editor experience | -If you find manual plugin configuration and MCP environment setup too cumbersome, check out our commercial version on **Fab**: -[**UMG MCP on Fab Marketplace**](https://www.fab.com/zh-cn/listings/f70dbcb0-11e4-46bf-b3f7-9f30ba2c9b71) +## Why It Exists -**Differences between Fab and Open Source versions:** -- **Out-of-the-Box**: The Fab version installs directly via the Unreal Engine launcher, eliminating the need for manual cloning and Python environment setup. -- **Context Compression**: The Fab version includes advanced context management, automatically filtering redundant MCP history to maximize available tokens for the AI. -- **Commercial Focus**: While the Open Source version is our protocol testbed, the Fab version is optimized for production business logic. Commercial users receive prioritized support for their specific integration challenges. -- **Maintained Parity**: We remain committed to open source; all core logic improvements will continue to be synced to this GitHub repository. +AI-assisted UI work needs more than screenshots. UMG assets are structured editor objects, and serious automation needs structured access. This project gives agents a protocol surface they can inspect, test, and improve without hiding behavior behind a black-box UI. ---- +The core design goals are: -### 🚀 Quick Start +- **Observable edits**: Every meaningful UI change should be expressible as a tool call and reviewable as data. +- **Versionable workflows**: UMG can be exported, patched, and reapplied as structured JSON. +- **Editor-native behavior**: Commands operate through Unreal editor systems instead of browser-style click automation. +- **Open protocol first**: The repository keeps the protocol, schemas, tests, and bug fixes public. -This guide covers the two-step process to install the `UmgMcp` plugin and connect it to your Gemini CLI. +## Quick Start -* **Prerequisite:** Unreal Engine 5.6 or newer. +Current target: **Unreal Engine 5.8 on Win64**. The plugin descriptor is set to `EngineVersion: 5.8.0`. -#### 1. Install the Plugin +### 1. Install The Plugin -1. **Navigate to your project's Plugins folder:** `YourProject/Plugins/` (create it if it doesn't exist). -2. **Clone the repository** directly into this directory: +Clone the open-source plugin into your Unreal project: - ```bash - git clone https://github.com/winyunq/UnrealMotionGraphicsMCP.git UmgMcp - ``` +```powershell +cd D:\UE5Project\YourProject +mkdir Plugins +cd Plugins +git clone https://github.com/winyunq/UnrealMotionGraphicsMCP.git UmgMcp +``` -3. **Restart the Unreal Editor.** This allows the engine to detect and compile the new plugin. +Open the project in Unreal Engine 5.8, enable `UmgMcp` if needed, and restart the editor so Unreal Build Tool can compile the plugin. -#### 2. Connect the Gemini CLI +### 2. Connect An MCP Client -Tell Gemini how to find and launch the MCP server. +Start Unreal Editor first. The plugin listens locally on `127.0.0.1:55557`; the Python MCP server forwards tool calls from your MCP client to that editor bridge. -1. **Edit your `settings.json`** file (usually located at `C:\Users\YourUsername\.gemini\`). -2. **Add the tool definition** to the `mcpServers` object. +Add this to your MCP client configuration, replacing the path with the absolute path to your project: - ```json - "mcpServers": { - "UmgMcp": { - "command": "uv", - "args": [ - "run", - "--directory", - "D:\\Path\\To\\YourUnrealProject\\Plugins\\UmgMcp\\Resources\\Python", - "UmgMcpServer.py" - ] - } +```json +{ + "mcpServers": { + "UmgMcp": { + "command": "uv", + "args": [ + "run", + "--directory", + "D:\\UE5Project\\YourProject\\Plugins\\UmgMcp\\Resources\\Python", + "UmgMcpServer.py" + ] } - ``` + } +} +``` + +Important details: + +- The `--directory` value must point to `Resources/Python`. +- Windows JSON paths need escaped backslashes, for example `D:\\UE5Project\\...`. +- Keep Unreal Editor open while using the MCP client. + +### 3. Verify The Setup + +Run protocol checks without opening a large test scenario: + +```powershell +cd D:\UE5Project\YourProject\Plugins\UmgMcp\Resources\Python +uv run python APITest\Umg_Widget_Protocol_Static_Check.py +uv run python APITest\Blueprint_MCP_Schema_Check.py +uv run python APITest\Material_Protocol_Static_Check.py +uv run python APITest\Animation_Protocol_Static_Check.py +``` + +Run an editor bridge smoke test after Unreal Editor is open: + +```powershell +uv run python APITest\UE5_Editor_Imitation.py +``` + +If you want a manual virtual environment: + +```powershell +cd D:\UE5Project\YourProject\Plugins\UmgMcp\Resources\Python +uv venv +.\.venv\Scripts\activate +uv pip install "mcp[cli]>=1.4.1" fastmcp uvicorn fastapi "pydantic>=2.6.1" requests +python -c "import mcp, fastapi, pydantic, requests; print('deps ok')" +``` + +## Documentation + +The documentation site is the best place for guided setup and usage: - **IMPORTANT:** You **must** replace the path with the correct **absolute path** to the `Resources/Python` folder from the cloned repository on your machine. +- [Web Manual](https://winyunq.github.io/UnrealMotionGraphicsMCP/) +- [Chinese Web Manual](https://winyunq.github.io/UnrealMotionGraphicsMCP/Document/index_zh.html) -That's it! When you start the Gemini CLI, it will automatically launch the MCP server in the background. +The repository keeps protocol references close to the code: -#### Testing the Connection +| Topic | File | +| --- | --- | +| Widget commands and JSON round-trip | [Document/UmgWidgetMcpProtocol.md](Document/UmgWidgetMcpProtocol.md) | +| Blueprint / BlueCode graph operations | [Document/BlueprintBluecodeProtocol.md](Document/BlueprintBluecodeProtocol.md) | +| Material and HLSL-oriented operations | [Document/MaterialMcpProtocol.md](Document/MaterialMcpProtocol.md) | +| Animation / Sequencer operations | [Document/AnimationMcpProtocol.md](Document/AnimationMcpProtocol.md) | -After restarting your Gemini CLI and opening your Unreal project, you can test the connection by calling any tool function: +## Example Agent Request -```python - cd Resources/Python/APITest - python UE5_Editor_Imitation.py +```text +Create /Game/UI/WBP_LoginPanel with a centered login card, email and password fields, +a primary submit button, and a subtle material background. Export the final widget JSON +and summarize which MCP tools changed the asset. ``` -#### Python Environment (Optional) +## Demos -The plugin's Python environment is managed by `uv`. In most cases, it should work automatically. If you encounter issues related to Python dependencies (e.g., `uv` command not found or module import errors), you can manually set up the environment: +- [Designing an RTS UI](https://youtu.be/O86VCzxyF5o) +- [Recreating the UE5 editor](https://youtu.be/h_J70I0m4Ls) +- [Editing UMG inside the UMG editor](https://youtu.be/pq12x2MH1L4) +- [Chatting with Gemini to edit a UMG file](https://youtu.be/93_Fiil9nd8) -1. Navigate to the directory: `cd YourUnrealProject/Plugins/UmgMcp/Resources/Python` -2. Run the setup: - ```bash - uv venv - .\.venv\Scripts\activate - uv pip install -e . - ``` +## Troubleshooting + +| Symptom | Fix | +| --- | --- | +| `ConnectionRefusedError`, `WinError 10061`, or `WinError 1225` | Open Unreal Editor first, enable `UmgMcp`, restart the editor, then reconnect the MCP client. | +| `uv` is not recognized | Install `uv`, restart the terminal, or create the manual virtual environment shown above. | +| Plugin does not compile | Confirm the project is UE 5.8 Win64, remove stale generated build output for this plugin/project, and let Unreal rebuild. | +| The wrong widget was edited | Set the active UMG target first or pass a full asset path such as `/Game/UI/WBP_LoginPanel.WBP_LoginPanel`. | + +## Open Source And Fab + +This repository is the open-source home of the UMG MCP protocol and editor bridge. The Fab package is an optional packaged distribution for users who prefer marketplace installation and production-focused packaging. Core protocol fixes should remain visible here so issues can be reported, reviewed, and reproduced in public. + +Fab listing: [UMG MCP on Fab Marketplace](https://www.fab.com/zh-cn/listings/f70dbcb0-11e4-46bf-b3f7-9f30ba2c9b71) + +## Contributing + +Good contributions include reproducible bug reports, focused protocol tests, payload examples, documentation fixes, and small editor-side fixes with clear before/after behavior. Please include your Unreal Engine version, plugin commit, target asset path, and the MCP payload that failed when reporting an issue. + +## License + +This repository is released under the [MIT License](LICENSE). --- -### 🧪 Experimental: Gemini CLI Skill Support +## Full Tool Surface And Legacy Manual + +The sections below are intentionally preserved from the previous README instead of being collapsed into a short landing page. They document experimental skill loading, prompt management, architecture notes, API status tables, compatibility tools, and the developer program. + +
+🧪 Experimental: Gemini CLI Skill Support -We are experimenting with the **Gemini CLI Skill** system as an alternative to the standard MCP approach. +We are experimenting with the **Gemini CLI Skill** system as an alternative to the standard MCP approach. The Skill architecture allows the Python tools to be loaded directly by the CLI runtime, potentially **optimizing context usage** by dynamically enabling/disabling tools via `prompts.json` and avoiding the overhead of managing a separate MCP server process. > **Note**: The MCP server (configured above) is still the stable and recommended way to use this plugin. Use Skill mode if you want to test the latest integration capabilities. @@ -115,9 +224,9 @@ To enable Skill mode, add the following to your `settings.json` (replacing ` -## English +--- This project provides a powerful, command-line driven workflow for managing Unreal Engine's UMG UI assets. By treating **human-readable `.json` files as the sole Source of Truth**, it fundamentally solves the challenge of versioning binary `.uasset` files in Git. @@ -125,7 +234,8 @@ Inspired by tools like `blender-mcp`, this system allows developers, UI designer --- -## Prompt Manager +
+📋 Prompt Manager A visual web tool for configuring system instructions, tool descriptions, and user prompt templates. @@ -143,7 +253,7 @@ Execute the following command in your Python environment: ```bash python Resources/Python/PromptManager/server.py ``` -The browser will automatically open `http://localhost:8085`。 +The browser will automatically open `http://localhost:8085`. ### Usage Tips @@ -155,18 +265,12 @@ Prompts are crucial for AI tool effectiveness. Use the Prompt Manager to tailor Contributions of effective prompt configurations are welcome! ---- - -### AI Authorship & Disclaimer - -This project has been developed with significant assistance from **Gemini, an AI**. As such: -* **Experimental Nature**: This is an experimental project. Its reliability is not guaranteed. -* **Commercial Use**: Commercial use is not recommended without thorough independent validation and understanding of its limitations. -* **Disclaimer**: Use at your own risk. The developers and AI are not responsible for any consequences arising from its use. +
--- -### Current Technical Architecture Overview +
+🏗️ Current Technical Architecture The system now primarily relies on the `UE5_UMG_MCP` plugin for communication between external clients (like this CLI) and the Unreal Engine Editor. @@ -184,52 +288,82 @@ flowchart LR end ``` -## API Status - -| Category | API Name | Status | -| --------------------------- | -------------------------------- | :----: | -| **Context & Attention** | `get_target_umg_asset` | ✅ | -| | `set_target_umg_asset` | ✅ | -| | `get_last_edited_umg_asset` | ✅ | -| | `get_recently_edited_umg_assets` | ✅ | -| **Sensing & Querying** | `get_widget_tree` | ✅ | -| | `query_widget_properties` | ✅ | -| | `get_creatable_widget_types` | ✅ | -| | `get_widget_schema` | ✅ | -| | `get_layout_data` | ✅ | -| | `check_widget_overlap` | ✅ | -| **Actions & Modifications** | `create_widget` | ✅ | -| | `delete_widget` | ✅ | -| | `set_widget_properties` | ✅ | -| | `reparent_widget` | ✅ | -| | `save_asset` | ✅ | -| **File Transformation** | `export_umg_to_json` | ✅ | -| | `apply_json_to_umg` | ✅ | -| | `apply_layout` | ✅ | - - ## UMG Blueprint API Status (New) - - | Category | API Name | Status | Description | - | --------------------------- | ------------------------- | :----: | ------------------------------------------------------------------------------------------------ | - | **Context & Attention** | `set_edit_function` | ✅ | Set the current edit context (Function/Event). Supports auto-creating Custom Events. | - | | `set_cursor_node` | ✅ | Explicitly set the "Cursor" node (Program Counter). | - | **Sensing & Querying** | `get_function_nodes` | ✅ | Get nodes in **Current Context Scope** (Filtered to connected graph to avoid global noise). | - | | `get_variables` | ✅ | Get list of member variables. | - | | `search_function_library` | ✅ | Search callable libraries (C++/BP). Supports Fuzzy Search. | - | **Actions & Modifications** | `add_step(name)` | ✅ | **Core**: Add executable node by Name (e.g. "PrintString"). Auto-Wiring & Auto-Layout supported. | - | | `prepare_value(name)` | ✅ | Add Data Node by Name (e.g. "MakeLiteralString", "GetVariable"). | - | | `connect_data_to_pin` | ✅ | Connect pins precisely (Supports `NodeID:PinName` format). | - | | `add_variable` | ✅ | Add new member variable. | - | | `delete_variable` | ✅ | Delete member variable. | - | | `delete_node` | ✅ | Delete specific node. | - | | `compile_blueprint` | ✅ | Compile and apply changes. | +
+ +--- + +
+⚖️ AI Authorship & Disclaimer + +This project has been developed with significant assistance from **Gemini, an AI**. As such: +* **Experimental Nature**: This is an experimental project. Its reliability is not guaranteed. +* **Commercial Use**: Commercial use is not recommended without thorough independent validation and understanding of its limitations. +* **Disclaimer**: Use at your own risk. The developers and AI are not responsible for any consequences arising from its use. + +
+ +--- + +## UMG Widget API Status + +| Category | API Name | Status | Description | +| --------------------------- | -------------------------------- | :----: | ------------------------------------------------------------------------------------------------ | +| **Context & Attention** | `get_target_umg_asset` | ✅ | Get the current active UMG asset path. | +| | `set_target_umg_asset` | ✅ | Set or create the target UMG asset. | +| | `get_last_edited_umg_asset` | ✅ | Get the last edited UMG asset path. | +| | `get_recently_edited_umg_assets` | ✅ | Get recently edited UMG assets list. | +| **Sensing & Querying** | `get_widget_tree` | ✅ | Get children of the widget target and show them as a tree (highly token-efficient). | +| | `query_widget_properties` | ✅ | Query specific properties of a widget. | +| | `get_creatable_widget_types` | ✅ | Get all creatable widget classes. | +| | `get_widget_schema` | ✅ | Get the property schema of a widget class. | +| | `get_layout_data` | ✅ | Get screen-space layout bounding boxes. | +| | `check_widget_overlap` | Hidden | Diagnostic compatibility tool; not exposed in the default prompt surface. | +| **Actions & Modifications** | `create_widget` | ✅ | Create a new widget. | +| | `delete_widget` | ✅ | Explicitly delete a widget; requires `confirm_delete=true`. | +| | `set_widget_properties` | ✅ | Set properties of a widget (omit widget_name to target active widget; union write fashion). | +| | `reorder_widget_tree` | ✅ | Reorder existing siblings from a partial tree without creating or deleting widgets. | +| | `reparent_widget` | ✅ | Convert/move a widget while preserving children where possible; child-loss cases fail. | +| | `save_asset` | ✅ | Save the active UMG asset. | +| | `apply_layout` | ✅ | Apply bulk layout definition (HTML/JSON). | +| **Hidden Compatibility** | `export_umg_to_json` | Hidden | Full JSON export for debug/compatibility; not part of the default semantic read flow. | +| | `apply_json_to_umg` | Hidden | Compatibility bulk JSON apply; prefer `apply_layout`. | + +Notes: +- UMG writes are append/upsert style: `create_widget` creates missing widgets and `set_widget_properties` only overwrites supplied properties. +- Deletion is explicit and hardened: `delete_widget` fails unless `confirm_delete=true` is supplied. + + +## UMG Blueprint API Status (Transitional) + +Blueprint MCP is still node-shaped. It is usable for simple event wiring, but it is not the final high-density `bluecode` protocol described in [Document/BlueprintBluecodeProtocol.md](Document/BlueprintBluecodeProtocol.md). + +| Category | API Name | Status | Description | +| --------------------------- | ------------------------- | :----: | --------------------------------------------------------------------------------------------------- | +| **Context & Attention** | `set_edit_function` | ✅ | Set the current edit context (Function/Event). Supports auto-creating Custom Events. | +| | `set_cursor_node` | Partial | Low-level cursor escape hatch for branches or repair flows. Prefer `set_edit_function` + append. | +| **Sensing & Querying** | `get_function_nodes` | Partial | Transitional node readback: IDs, node names/classes, and exec flags only. | +| | `get_variables` | ✅ | Get list of member variables. | +| | `search_function_library` | ✅ | Search callable libraries (C++/BP). Supports fuzzy search. | +| **Union Writes** | `add_step(name)` | ✅ | Add executable node by name (e.g. "PrintString"). Auto-wiring and auto-layout supported. | +| | `prepare_value(name)` | ✅ | Add data node by name (e.g. "MakeLiteralString", "GetVariable"). | +| | `connect_data_to_pin` | ✅ | Connect pins precisely (supports `NodeID:PinName` format). | +| | `add_variable` | ✅ | Add or update a member variable; do not remove unspecified variables. | +| | `compile_blueprint` | ✅ | Compile and apply changes. | +| **Hidden Compatibility** | `delete_variable` | Hidden | Backend compatibility only; hidden from default MCP until deletion requires `confirm_delete=true`. | +| | `delete_node` | Hidden | Backend compatibility only; hidden from default MCP until deletion requires `confirm_delete=true`. | + +Notes: +- Current Blueprint reads are not yet semantically dense enough to answer "read any information" well. +- `bluecode` should introduce code-like read/write, append-only merge semantics, explicit `bluecode_delete(confirm_delete=true)`, and compact compile diagnostics. +- Until then, use Blueprint MCP only for narrow event wiring and verify with `compile_blueprint` plus focused readback. ## UMG Sequencer API Status | Command | Status | Description | | :------------------------------- | :----: | :--------------------------------------------------------------------------------------------------------------- | -| `animation_target` | ✅ | Set/focus the current animation (alias of `set_animation_scope`, auto-creates when missing). | -| `widget_target` | ✅ | Set/focus the current widget (alias of `set_widget_scope`). | +| `set_animation_scope` | ✅ | Animation target: focus the current animation and auto-create it when missing. | +| `set_widget_scope` | ✅ | Widget target inside the current animation. | +| `get_all_animations` | ✅ | Compact animation list for the active UMG target. | | `animation_overview` | ✅ | Returns keyframe counts, track counts, key times, and changed properties. | | `animation_widget_properties` | ✅ | Timeline view: per-widget property changes (ignores unanimated properties). | | `animation_time_properties` | ✅ | Time-slice view: property values at specific times (multi-time supported). | @@ -237,46 +371,33 @@ flowchart LR | `animation_append_time_slice` | ✅ | Append a diff-style time slice for multiple widgets at a given time. | | `animation_delete_widget_keys` | ✅ | Scoped delete for widget+property at specific times (`confirm_delete=true` required per Issue 15 safety policy). | | `create_animation` | ✅ | Create or focus an animation with auto naming. | -| `set_property_keys` | ✅ | Low-level track write helper (supports float/color/vector2D). | +| `delete_animation` | ✅ | Explicit whole-animation delete; requires `confirm_delete=true`. | Notes: -- `animation_target`/`widget_target` reuse the current UMG target asset; names are auto-corrected (no “animal” typo) and auto-create when missing. +- `set_animation_scope`/`set_widget_scope` implement the target/default semantics from the protocol; names are auto-corrected (no "animal" typo) and animations auto-create when missing. - Write paths are union/overwrite only—no implicit deletion. Use `animation_delete_widget_keys` with `confirm_delete=true` for scoped removals. -- Responses now include counts/timeline context so every sequencer MCP returns actionable data. - -## UMG Material API Status (New: The 5 Core Pillars Strategy) - -| Category | API Name | Status | Description | -| ----------------------- | ------------------------------ | :-------: | ----------------------------------------------------------------------------------------------- | -| **P0: Context** | `material_set_target` | ✅ | **Anchor**: Specify target asset (path or parent). Required for stateful editing. | -| **P1: Def & Query** | `material_define_variable` | ✅ | Define external interface parameters (Def, not wire). Supports Scalar, Vector, Texture. | -| **P2: Symbol Place** | `material_add_node` | ✅ | **Drag Symbol**: Place a symbol from lib into graph and assign a unique instance handle. | -| | `material_get_graph` | ✅ | Query existence and state of node instances in the graph. | -| **P3: Connectivity** | `material_connect_nodes` | ✅ | **Natural Connection**: Establish node-to-node functional flow (A -> B). | -| | `material_connect_pins` | ✅ | **Surgical Wiring**: Manually connect specific pins for complex topologies. | -| **P4: Lib Search** | `material_search_library` | 🚧 Planned | Search for available Material Expressions (symbols) and Functions. | -| **P5: Tactical Detail** | `material_set_hlsl_node_io` | ✅ | **Tactical Code**: Inject HLSL into Custom nodes and sync IO pins via JSON mapping. | -| | `material_set_node_properties` | ✅ | **Property Editing**: Set internal properties for regular nodes (e.g. Constant Value, Texture). | -| **Lifecycle** | `material_compile_asset` | ✅ | Submit changes and analyze HLSL compilation errors. | -| **Maintenance** | `material_delete` | ✅ | Delete node instances or clean up logic by unique handle. | -| | `material_get_pins` | ✅ | Introspect pins for a specific node handle. | - -## UMG HLSL MCP API Status (New: Text-Edit Loop for UMG) - -| Command | Status | Description | -| ------------------- | :----: | ------------------------------------------------------------------------------------------------------------------------------------- | -| `hlsl_set_target` | ✅ | Lock/create HLSL target material. Validates UI-domain + single Custom node topology; can request confirmation before overwrite. | -| `hlsl_get` | ✅ | Read current HLSL code and structured input parameters from the single Custom node. | -| `hlsl_set` | ✅ | Incremental update of HLSL and/or parameters. Deletion is explicit (`delete: true`) to avoid accidental destructive edits. | -| `hlsl_compile` | ✅ | Compile current HLSL target and return concise diagnostics for AI post-processing. | +- Legacy low-level reads/writes such as `get_animation_keyframes`, `get_animation_full_data`, `set_property_keys`, `set_animation_data`, `remove_property_track`, and `remove_keys` remain backend compatibility commands but are hidden from the default MCP prompt surface. +- Responses include counts/timeline context so every default Sequencer MCP returns actionable data. + +## UMG Material API Status + +| Command | Status | Description | +| ----------------- | :----: | ---------------------------------------------------------------------------------------------------------------- | +| `hlsl_set_target` | ✅ | Lock/create the HLSL target material. New assets default to UI; pass type fields for non-UMG materials. | +| `hlsl_get` | ✅ | Read current HLSL code, structured parameters, and the semantic output contract. | +| `hlsl_set` | ✅ | Union-style write for HLSL, parameters, and extra outputs: overwrite existing items and append missing ones. | +| `hlsl_delete` | ✅ | Explicitly delete HLSL parameters or outputs with `confirm_delete=true`; add `kind` only when a name is ambiguous. | +| `hlsl_compile` | ✅ | Compile current HLSL target and return concise diagnostics for AI post-processing. | ### HLSL Protocol Contract (UMG-Optimized) - Material is treated as a single HLSL program. - Backend assumes HLSL returns `float4`. -- Output auto-wiring is fixed: `.rgb -> FinalColor`, `.a -> Opacity`. +- Output auto-wiring is semantic: UI/Post Process/Light Function/Unlit routes rgb to `EmissiveColor`; Lit Surface routes rgb to `BaseColor`; alpha only connects to `Opacity` or `OpacityMask` when needed. +- Extra material outputs use UE 5.8 Custom node `AdditionalOutputs`, so one HLSL block can drive `Roughness`, `Metallic`, `Normal`, `WorldPositionOffset`, and similar root outputs. - Input parameters are returned as structured descriptors (`name`, `kind`, `source_handle`) for learning/replay by AI agents. -- `hlsl_set` is safety-biased: writing is easy, deletion must be explicit. +- `hlsl_set` only performs union overwrite/append operations. Deletion must use `hlsl_delete(confirm_delete=true)`. +- Low-level `material_*` graph tools are kept as a compatibility layer, but the Material ToolMode exposes the HLSL loop by default. ## UMG Style & Theming API Status (New) @@ -286,6 +407,45 @@ Notes: | **Theming** | `apply_global_theme` | 🚧 Planned | Batch apply styles and fonts across multiple widgets based on a theme config. | | **Assets** | `style_create_asset` | 🚧 Planned | Create a standalone Slate Widget Style asset. | -## Project Status Update +--- + +## Developer Program + +> We notice there are many forks but few PRs — here's your invitation to change that. + +
+❓ What is the Developer Program & Why does it exist? + +We are living in the age of AI. Everyone now has the ability to build and contribute to projects with AI assistance. UMG MCP is sincerely provided free of charge for everyone to learn and use — and this should include the Fab version too. + +By joining the Developer Program and meeting the contribution criteria, **you will gain access to the private repository during your active development period**. + +
+ +
+🎁 Why is the reward a Fab version license? + +The only reason the Fab version is paid is an economic reality: if it were free, the average social return on labor would drop dramatically. Charging for it is the only mechanism to sustain development. The Fab version of UMG MCP *should* be free — but making it truly free would only force us to work harder for less. Therefore, rewarding contributors with a Fab license serves two purposes: it gives you access to the more polished version, and it gives you the ability to maintain the real, production-grade project. + +
+ +
+🛠️ How to join the UMG MCP Developer Program? + +This is admittedly a bit of a paradox — UMG MCP is designed to serve non-programmers, and programmers may not need it as much. Regardless, here are the paths to contribute: + +**Path 1 — Video Content:** +Create a video specifically about the UMG MCP **Fab version**. Reach a meaningful audience and we'll count it. + +**Path 2 — Feature Development:** +Our design philosophy is simple: *if your tool gets accepted, you're in*. Develop a feature, submit a PR, and if we merge it, you qualify. + +**Path 3 — Prompt Engineering:** +Write system prompts that help the AI more accurately identify and invoke the correct tools — even when all tools are enabled simultaneously. Precision matters here. + +**Path 4 — Purchase the Fab version:** +If you've purchased it, you already have the right to access this project. Simple as that. + +**To apply:** Send your GitHub profile to **winyunq@gmail.com** -I'm sorry, due to Google's cancellation of my student discount, my free time to advance this project is limited. But don't worry, as this has forced me to use AIs from other platforms, which might actually accelerate the support for other platforms in this plugin. Specifically, our upcoming development plan is to add various API key access in the Fab version because I believe you are all tech-savvy, but those who truly need UMG are artists who may not have a technical background. In any case, if you could purchase a paid version of UMG MCP on Fab, that would be wonderful—maybe I could then directly subscribe to Gemini AI for development? +
diff --git a/Readme_zh.md b/Readme_zh.md index 6d7a7f0..5faad64 100644 --- a/Readme_zh.md +++ b/Readme_zh.md @@ -1,176 +1,280 @@ -[English version please click here](Readme.md) +[English](Readme.md) + +
+

UnrealMotionGraphicsMCP

+

面向 Unreal Engine UMG 自动化制作的开源 MCP 工具集。

+

+ 网页教程 + · 快速开始 + · 协议文档 + · Issues + · Discord +

+

+ License MIT + Unreal Engine 5.8 + Platform Win64 + AgentSeal MCP +

+
-# UE5-UMG-MCP 🤖📄 +--- -**版本受控的 AI 辅助 UMG 工作流** +**UnrealMotionGraphicsMCP** 让 AI Agent 可以通过明确、可版本化的 MCP 命令编辑 Unreal UMG。它不要求 Agent 靠截图猜测,也不依赖脆弱的自动点击,而是把真实的编辑器状态暴露出来:Widget Tree、Slot 属性、Blueprint 图表操作、UI 材质、动画轨道,以及 UMG JSON 导出/回写。 -![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)![Status: Experimental](https://img.shields.io/badge/status-experimental-red.svg)![Built with AI](https://img.shields.io/badge/Built%20with-AI%20Assistance-blueviolet.svg)[![AgentSeal MCP](https://agentseal.org/api/v1/mcp/https-githubcom-winyunq-unrealmotiongraphicsmcp/badge)](https://agentseal.org/mcp/https-githubcom-winyunq-unrealmotiongraphicsmcp) +开源插件是协议与编辑器桥接本体。它应该是可阅读、可调试、可复现的,适合研究、自定义管线、Issue 汇报和社区修复。 -[Demo 设计 RTS UI](https://youtu.be/O86VCzxyF5o) +## 这个项目能做什么 -[Demo 在 UMG 窗口中复现 UE5 编辑器预览](https://youtu.be/h_J70I0m4Ls) +| 范围 | 开源能力 | +| --- | --- | +| UMG Widget | 创建控件、读取树结构、设置属性和 Slot、重排子节点、替换子树、导出和回写 JSON | +| Blueprint / BlueCode | 创建图表节点、连接 Pin、绑定 Widget 引用、应用紧凑的代码式图表语句 | +| Material | 创建 UI 材质、设置参数、添加支持的表达式、测试面向 HLSL 的材质工作流 | +| Animation | 为 Render Transform、Opacity、Color 和 Timing 创建 UMG 动画轨道与关键帧 | +| Editor Bridge | 让外部 MCP 客户端通过 `127.0.0.1:55557` 的本机桥接调用 Unreal Editor | -[Demo 在 UMG 编辑器中操作 UMG 控件](https://youtu.be/pq12x2MH1L4) +## 版本边界 -[与 Gemini 3 对话编辑 UMG 文件](https://youtu.be/93_Fiil9nd8) +UMG MCP 是一个公开项目,但实际使用上有两条路径: ---- +- **开源版**:公开协议、Unreal 编辑器桥接、Python MCP server、工具 schema、测试和协议文档。 +- **Fab / FabServer 版**:闭源打包产品层,面向需要编辑器内 Chat、Provider 配置 UI、审批队列、本地模型和更少手动安装步骤的用户。 -### 🛍️ 需要更便捷的使用体验?尝试 Fab 版! +| 能力 | 开源版 | Fab / FabServer 版 | +| --- | --- | --- | +| 核心 UMG Widget MCP 工具 | 有 | 有 | +| Widget Tree 读取、属性修改、布局 append/upsert、JSON 导出/回写 | 有 | 有 | +| Blueprint / BlueCode 协议方向和节点级桥接 | 有 | 有 | +| Sequencer / UMG 动画工具 | 有 | 有 | +| Material 与 HLSL 工作流 | 有 | 有 | +| 面向外部客户端的 Python MCP server | 有,需要手动配置 `Resources/Python` | 共享协议仍可使用,但产品主路径是编辑器内工作流 | +| 手动 clone/build 工作流 | 有 | 不需要,通过 Fab / Unreal Launcher 安装 | +| 编辑器内 ChatWithUnreal 面板 | 无 | 有 | +| FabServer 审批队列与内存直连执行 | 无 | 有 | +| chat、develop、learning、task 等内置 Agent 模式 | 无 | 有 | +| Google OAuth、API Key、智谱 AI、OpenAI 兼容端点等 Provider 设置 UI | 无 | 有 | +| 本地 LiteRT-LM 集成 | 无 | 有 | +| 上下文压缩 / 生产级对话管理 | 无 | 有 | +| 最适合 | 开发者、研究者、贡献者、自定义 MCP 管线 | 美术、技术美术、生产团队、希望获得完整编辑器体验的用户 | -如果您觉得手动配置插件和 MCP 环境过于繁琐,可以尝试我们在 **Fab** 上架的商业化版本: -[**Fab 版 UMG MCP 直达链接**](https://www.fab.com/zh-cn/listings/f70dbcb0-11e4-46bf-b3f7-9f30ba2c9b71) +## 为什么需要它 -**Fab 版与开源版的区别:** -- **开箱即用**:Fab 版可以直接通过虚幻引擎后台安装,无需手动克隆和配置 Python 环境。 -- **上下文压缩 (Context Compression)**:Fab 版内置了更智能的上下文管理,底层会自动过滤冗余的 MCP 历史信息,为 AI 腾出更多可用的 Token。 -- **商业化支持**:Fab 版侧重于生产环境的商业逻辑。如果您在商业项目中遇到困难,我们将提供更优先的技术支持和解决方案。 -- **持续同步**:开源版 (GitHub) 依然是我们的协议先行地,所有核心功能的更新都会同步到开源版本中。 +AI 辅助 UI 制作不能只靠截图。UMG 资产是结构化编辑器对象,严肃的自动化需要结构化访问。这个项目给 Agent 一个可以检查、测试和改进的协议表面,而不是把行为藏在黑盒 UI 操作里。 ---- +核心目标: -### 🚀 快速开始 +- **可观察的编辑**:每个关键 UI 修改都应该能表示为工具调用,并能作为数据审查。 +- **可版本化的工作流**:UMG 可以导出为结构化 JSON,再按补丁回写。 +- **编辑器原生行为**:命令通过 Unreal 编辑器系统执行,而不是模拟浏览器式点击。 +- **开源协议优先**:协议、schema、测试和 bug fix 都应该保留在公开仓库。 -本指南涵盖了安装 `UmgMcp` 插件并将其连接到 Gemini CLI 的两个步骤。 +## 快速开始 -* **前提条件:** Unreal Engine 5.6 或更高版本。 +当前目标平台:**Unreal Engine 5.8 / Win64**。插件描述文件的 `EngineVersion` 是 `5.8.0`。 -#### 1. 安装插件 (Install the Plugin) +### 1. 安装插件 -1. **进入项目的 Plugins 文件夹:** `YourProject/Plugins/`(如果不存在则创建)。 -2. **直接克隆仓库**到此目录: +把开源插件克隆到 Unreal 项目: - ```bash - git clone https://github.com/winyunq/UnrealMotionGraphicsMCP.git UmgMcp - ``` +```powershell +cd D:\UE5Project\YourProject +mkdir Plugins +cd Plugins +git clone https://github.com/winyunq/UnrealMotionGraphicsMCP.git UmgMcp +``` -3. **重启 Unreal Editor。** 这允许引擎检测并编译新插件。 +用 Unreal Engine 5.8 打开项目,必要时启用 `UmgMcp`,然后重启编辑器,让 Unreal Build Tool 编译插件。 -#### 2. 连接 Gemini CLI (Connect the Gemini CLI) +### 2. 连接 MCP 客户端 -告诉 Gemini 如何找到并启动 MCP 服务器。 +先启动 Unreal Editor。插件会在本机监听 `127.0.0.1:55557`,Python MCP server 会把 MCP 客户端的工具调用转发到这个编辑器桥接。 -1. **编辑您的 `settings.json`** 文件(通常位于 `C:\Users\用户名\.gemini\`)。 -2. **将工具定义添加**到 `mcpServers` 对象中。 +把下面配置加入 MCP 客户端,并把路径替换为你项目里的插件绝对路径: - ```json - "mcpServers": { - "UmgMcp": { - "command": "uv", - "args": [ - "run", - "--directory", - "D:\\Path\\To\\YourUnrealProject\\Plugins\\UmgMcp\\Resources\\Python", - "UmgMcpServer.py" - ] - } +```json +{ + "mcpServers": { + "UmgMcp": { + "command": "uv", + "args": [ + "run", + "--directory", + "D:\\UE5Project\\YourProject\\Plugins\\UmgMcp\\Resources\\Python", + "UmgMcpServer.py" + ] } - ``` + } +} +``` + +注意: + +- `--directory` 必须指向 `Resources/Python`。 +- Windows JSON 路径要转义,例如 `D:\\UE5Project\\...`。 +- 使用 MCP 客户端时请保持 Unreal Editor 打开。 - **注意:** 您**必须**将路径替换为您机器上克隆仓库中 `Resources/Python` 文件夹的正确**绝对路径**。 +### 3. 验证安装 -就是这样!当您启动 Gemini CLI 时,它将自动在后台启动 MCP 服务器。 +先跑静态协议检查: -#### 测试连接 +```powershell +cd D:\UE5Project\YourProject\Plugins\UmgMcp\Resources\Python +uv run python APITest\Umg_Widget_Protocol_Static_Check.py +uv run python APITest\Blueprint_MCP_Schema_Check.py +uv run python APITest\Material_Protocol_Static_Check.py +uv run python APITest\Animation_Protocol_Static_Check.py +``` + +打开 Unreal Editor 后,再跑编辑器桥接冒烟测试: + +```powershell +uv run python APITest\UE5_Editor_Imitation.py +``` -重启 Gemini CLI 并打开 Unreal 项目后,您可以通过调用任何工具函数来测试连接: +如果你希望手动创建虚拟环境: -```python - cd Resources/Python/APITest - python UE5_Editor_Imitation.py +```powershell +cd D:\UE5Project\YourProject\Plugins\UmgMcp\Resources\Python +uv venv +.\.venv\Scripts\activate +uv pip install "mcp[cli]>=1.4.1" fastmcp uvicorn fastapi "pydantic>=2.6.1" requests +python -c "import mcp, fastapi, pydantic, requests; print('deps ok')" ``` -#### Python 环境(可选) +## 文档 -插件的 Python 环境由 `uv` 管理。在大多数情况下,它应该会自动工作。如果您遇到与 Python 依赖项相关的问题(例如找不到 `uv` 命令或模块导入错误),您可以手动设置环境: +引导式安装与使用说明放在网页文档: -1. 导航到目录:`cd YourUnrealProject/Plugins/UmgMcp/Resources/Python` -2. 运行设置: - ```bash - uv venv - .\.venv\Scripts\activate - uv pip install -e . - ``` +- [网页教程](https://winyunq.github.io/UnrealMotionGraphicsMCP/Document/index_zh.html) +- [English Web Manual](https://winyunq.github.io/UnrealMotionGraphicsMCP/) + +协议文档保留在仓库内,便于和代码一起审查: + +| 主题 | 文件 | +| --- | --- | +| Widget 命令和 JSON 回写 | [Document/UmgWidgetMcpProtocol.md](Document/UmgWidgetMcpProtocol.md) | +| Blueprint / BlueCode 图表操作 | [Document/BlueprintBluecodeProtocol.md](Document/BlueprintBluecodeProtocol.md) | +| Material 与 HLSL 相关操作 | [Document/MaterialMcpProtocol.md](Document/MaterialMcpProtocol.md) | +| Animation / Sequencer 操作 | [Document/AnimationMcpProtocol.md](Document/AnimationMcpProtocol.md) | + +## Agent 任务示例 + +```text +创建 /Game/UI/WBP_LoginPanel:居中的登录卡片、邮箱和密码输入框、 +主按钮,以及一个轻量材质背景。完成后导出最终 Widget JSON, +并总结本次修改用到了哪些 MCP 工具。 +``` + +## 视频演示 + +- [设计 RTS UI](https://youtu.be/O86VCzxyF5o) +- [复现 UE5 编辑器](https://youtu.be/h_J70I0m4Ls) +- [在 UMG 编辑器中编辑 UMG](https://youtu.be/pq12x2MH1L4) +- [和 Gemini 对话编辑 UMG 文件](https://youtu.be/93_Fiil9nd8) + +## 常见问题 + +| 现象 | 处理方式 | +| --- | --- | +| `ConnectionRefusedError`、`WinError 10061` 或 `WinError 1225` | 先打开 Unreal Editor,启用 `UmgMcp`,重启编辑器,然后重新连接 MCP 客户端。 | +| 系统找不到 `uv` | 安装 `uv` 后重开终端,或使用上面的手动虚拟环境流程。 | +| 插件无法编译 | 确认项目使用 UE 5.8 Win64,清理该插件/项目的旧生成产物,然后让 Unreal 重新构建。 | +| Agent 改错了 Widget | 先设置当前 UMG 目标,或传完整资产路径,例如 `/Game/UI/WBP_LoginPanel.WBP_LoginPanel`。 | + +## 开源与 Fab + +这个仓库是 UMG MCP 协议与编辑器桥接的开源主页。Fab 包是可选的打包发行版,适合希望通过市场安装并获得更生产化封装的用户。核心协议修复应当保留在公开仓库,方便公开汇报、审查和复现。 + +Fab 链接:[UMG MCP on Fab Marketplace](https://www.fab.com/zh-cn/listings/f70dbcb0-11e4-46bf-b3f7-9f30ba2c9b71) + +## 贡献 + +有效贡献包括可复现的 bug 报告、聚焦的协议测试、payload 示例、文档修复,以及行为清楚的小型编辑器侧修复。提交 Issue 时请尽量包含 Unreal Engine 版本、插件 commit、目标资产路径和失败的 MCP payload。 + +## 许可证 + +本仓库使用 [MIT License](LICENSE)。 --- -### 🧪 实验性功能:Gemini CLI Skill 支持 +## 完整工具表与旧版手册内容 -我们正在尝试使用 **Gemini CLI Skill** 系统作为标准 MCP 方法的替代方案。 -Skill 架构允许 Python 工具直接由 CLI 运行时加载,通过 `prompts.json` 动态启用/禁用工具,潜在地**优化上下文使用**,并避免管理独立 MCP 服务器进程的开销。 +下面这些内容是从旧版 README 并集合并回来的,不再折叠或隐藏 UMG MCP 的工具面。API 名称、payload 约定和工具状态保留英文原文,避免翻译导致 tool 名称失真。 -> **注意**:上面配置的 MCP 服务器仍然是使用此插件的稳定且推荐的方式。如果您想测试最新的集成能力,请使用 Skill 模式。 +
+🧪 Experimental: Gemini CLI Skill Support -#### 配置 (Skill 模式) +We are experimenting with the **Gemini CLI Skill** system as an alternative to the standard MCP approach. +The Skill architecture allows the Python tools to be loaded directly by the CLI runtime, potentially **optimizing context usage** by dynamically enabling/disabling tools via `prompts.json` and avoiding the overhead of managing a separate MCP server process. -要启用 Skill 模式,请将以下内容添加到您的 `settings.json` 中(替换 ``): +> **Note**: The MCP server (configured above) is still the stable and recommended way to use this plugin. Use Skill mode if you want to test the latest integration capabilities. + +#### Configuration (Skill Mode) + +To enable Skill mode, add the following to your `settings.json` (replacing ``): ```json "skills": { "unreal_umg": { "path": "/Plugins/UmgMcp/Resources/Python/UmgMcpSkills.py", "type": "local", - "description": "通过 Python Skills 直接控制 Unreal Engine UMG。从 prompts.json 自动加载工具。" + "description": "Direct control of Unreal Engine UMG via Python Skills. Auto-loads tools from prompts.json." } }, ``` ---- +
-## 简体中文 (Chinese) +--- -本项目为管理 Unreal Engine 的 UMG UI 资产提供了一个强大的、命令行驱动的工作流。通过将 **人类可读的 `.json` 文件视为唯一的真理源 (Source of Truth)**,它从根本上解决了在 Git 中对二进制 `.uasset` 文件进行版本控制的挑战。 +This project provides a powerful, command-line driven workflow for managing Unreal Engine's UMG UI assets. By treating **human-readable `.json` files as the sole Source of Truth**, it fundamentally solves the challenge of versioning binary `.uasset` files in Git. -受 `blender-mcp` 等工具的启发,该系统允许开发人员、UI 设计师和 AI 助手以编程方式与 UMG 资产进行交互,从而实现真正的 Git 协作、自动化 UI 生成和迭代。 +Inspired by tools like `blender-mcp`, this system allows developers, UI designers, and AI assistants to interact with UMG assets programmatically, enabling true Git collaboration, automated UI generation, and iteration. --- -## Prompt 管理器 (Prompt Manager) +
+📋 Prompt Manager -一个用于配置系统指令、工具描述和用户提示模板的可视化 Web 工具。 +A visual web tool for configuring system instructions, tool descriptions, and user prompt templates. -### 功能 +### Features -1. **系统指令编辑器**:修改针对 AI 上下文的全局指令。 -2. **工具管理**: - * **启用/禁用**:开启或关闭特定的 MCP 工具。禁用的工具不会在 MCP 服务器上注册,从而有效地**压缩上下文窗口**,防止 AI 分心。 - * **编辑描述**:自定义工具描述(提示词),使其更符合您的工作流。 -3. **用户模板 (Prompts)**:添加可重用的提示词模板,方便 MCP 客户端快速访问。 +1. **System Instruction Editor**: Modify the global instructions for the AI context. +2. **Tool Management**: + * **Enable/Disable**: Toggle specific MCP tools on or off. Disabled tools are not registered with the MCP server, effectively **compressing the context window** to prevent AI distraction. + * **Edit Descriptions**: Customize tool descriptions (prompts) to better suit your workflow. +3. **User Templates (Prompts)**: Add reusable prompt templates for quick access by the MCP client. -### 如何运行 +### How to Run -在您的 Python 环境中执行以下命令: +Execute the following command in your Python environment: ```bash python Resources/Python/PromptManager/server.py ``` -浏览器将自动打开 `http://localhost:8085`。 - -### 使用提示 +The browser will automatically open `http://localhost:8085`. -Prompt 对 AI 工具的有效性至关重要。使用 Prompt 管理器来为 AI 量身定制其行为: +### Usage Tips -* **一键部署模式**:如果您希望 AI 仅专注于根据设计生成 UI,请禁用除 `apply_layout` 和 `export_umg_to_json` 之外的所有工具。 -* **导师模式**:如果您希望 AI 只是进行指导而不做逻辑更改,请仅保留只读工具(例如 `get_widget_tree`, `get_widget_schema`)。 -* **上下文优化**:对于上下文窗口较小的模型,禁用当前不使用的工具以提高速度和准确性。 +Prompts are crucial for AI tool effectiveness. Use the Prompt Manager to tailor the AI's behavior: -欢迎贡献有效的 Prompt 配置! - ---- +* **One-Click Deployment Mode**: If you want the AI to focus solely on generating UI from design, disable all tools except `apply_layout` and `export_umg_to_json`. +* **Tutor Mode**: If you want the AI to guide you without making changes, keep only read-only tools (e.g., `get_widget_tree`, `get_widget_schema`). +* **Context Optimization**: For models with smaller context windows, disable tools you aren't currently using to improve speed and accuracy. -### AI 署名与免责声明 +Contributions of effective prompt configurations are welcome! -本项目是在 **Gemini (一种 AI)** 的显著协助下开发的。因此: -* **实验性质**:这是一个实验性项目,不保证其可靠性。 -* **商业用途**:在没有经过彻底的独立验证和了解其局限性的情况下,不建议用于商业用途。 -* **免责声明**:使用风险自负。开发人员和 AI 对因使用本项目而产生的任何后果概不负责。 +
--- -### 当前技术架构概览 +
+🏗️ Current Technical Architecture -系统目前主要依靠 `UE5_UMG_MCP` 插件在外部客户端(如本 CLI)与 Unreal Engine 编辑器之间进行通信。 +The system now primarily relies on the `UE5_UMG_MCP` plugin for communication between external clients (like this CLI) and the Unreal Engine Editor. -**架构图:** +**Architecture Diagram:** ```mermaid flowchart LR @@ -184,108 +288,164 @@ flowchart LR end ``` -## API 实现状态 - -| 分类 | API 名称 | 状态 | -| ------------------ | -------------------------------- | :---: | -| **上下文与注意力** | `get_target_umg_asset` | ✅ | -| | `set_target_umg_asset` | ✅ | -| | `get_last_edited_umg_asset` | ✅ | -| | `get_recently_edited_umg_assets` | ✅ | -| **感知与查询** | `get_widget_tree` | ✅ | -| | `query_widget_properties` | ✅ | -| | `get_creatable_widget_types` | ✅ | -| | `get_widget_schema` | ✅ | -| | `get_layout_data` | ✅ | -| | `check_widget_overlap` | ✅ | -| **动作与修改** | `create_widget` | ✅ | -| | `delete_widget` | ✅ | -| | `set_widget_properties` | ✅ | -| | `reparent_widget` | ✅ | -| | `save_asset` | ✅ | -| **文件转换** | `export_umg_to_json` | ✅ | -| | `apply_json_to_umg` | ✅ | -| | `apply_layout` | ✅ | - -## UMG 蓝图 (Blueprint) API 实现状态 (New) - -| 分类 | API 名称 | 状态 | 描述 | -| ------------------ | ------------------------- | :---: | -------------------------------------------------------------- | -| **上下文与注意力** | `set_edit_function` | ✅ | 设置当前编辑上下文(函数/事件)。支持自动创建自定义事件。 | -| | `set_cursor_node` | ✅ | 显式设置“光标”节点(程序计数器)。 | -| **感知与查询** | `get_function_nodes` | ✅ | 获取**当前上下文作用域**内的节点(过滤掉无关节点以减少噪音)。 | -| | `get_variables` | ✅ | 获取成员变量列表。 | -| | `search_function_library` | ✅ | 搜索可调用的库 (C++/BP)。支持模糊搜索。 | -| **动作与修改** | `add_step(name)` | ✅ | **核心**:根据名称添加可执行节点。支持自动连线与布局。 | -| | `prepare_value(name)` | ✅ | 添加数据节点(例如 GetVariable)。 | -| | `connect_data_to_pin` | ✅ | 精确连接引脚(支持 `NodeID:PinName` 格式)。 | -| | `add_variable` | ✅ | 添加新的成员变量。 | -| | `delete_variable` | ✅ | 删除成员变量。 | -| | `delete_node` | ✅ | 删除特定节点。 | -| | `compile_blueprint` | ✅ | 编译并应用更改。 | - -## UMG 动画 (Sequencer) API 实现状态 - -| 命令 | 状态 | 描述 | -| :----------------------------- | :------: | :------------------------------------------------------------------------------------ | -| `animation_target` | ✅ 已实现 | 设置/聚焦当前动画(等价 `set_animation_scope`,若不存在会自动创建)。 | -| `widget_target` | ✅ 已实现 | 设置/聚焦当前控件(等价 `set_widget_scope`)。 | -| `animation_overview` | ✅ 已实现 | 返回关键帧数量、轨道数量、关键时间点、变更的属性列表。 | -| `animation_widget_properties` | ✅ 已实现 | 按控件视角查看属性时间线(忽略未被动画驱动的属性)。 | -| `animation_time_properties` | ✅ 已实现 | 按时间切片查看属性值,支持一次查询多个时间点。 | -| `animation_append_widget_tracks` | ✅ 已实现 | 按控件+属性批量追加/覆盖关键帧(仅并集/覆盖,不做删除)。 | -| `animation_append_time_slice` | ✅ 已实现 | 在指定时间为多个控件追加差分式属性值。 | -| `animation_delete_widget_keys` | ✅ 已实现 | 仅删除指定控件+属性在指定时间的关键帧(需 `confirm_delete=true`,符合 Issue 15 安全策略)。 | -| `create_animation` | ✅ 已实现 | 创建或聚焦动画,支持自动命名。 | -| `set_property_keys` | ✅ 已实现 | 底层轨道写入辅助(支持 float/color/vector2D)。 | - -说明: -- `animation_target` / `widget_target` 复用当前 UMG 目标资产,命名自动纠错(不再出现 “animal” 拼写),并在缺失时自动创建。 -- 写入仅做并集/覆盖,不做隐式删除;如需删除,请使用 `animation_delete_widget_keys` 并显式传入 `confirm_delete=true`。 -- 所有动画指令都会返回有价值的计数/时间线信息,便于 AI 复述与复现。 - -## UMG 材质 (Material) API 实现状态 (New: 五大核心能力) - -| 分类 | API 名称 | 状态 | 描述 | -| ---------------- | ------------------------------ | :------: | ---------------------------------------------------------------------- | -| **P0: 上下文** | `material_set_target` | ✅ | **锚点**:指定当前编辑的材质资产(支持自动创建/重定向)。 | -| **P1: 输入定义** | `material_define_variable` | ✅ | 定义外部接口参数(定义而非连线)。支持 Scalar, Vector, Texture。 | -| **P2: 符号放置** | `material_add_node` | ✅ | **拖拽符号**:将 UE5 库中的符号放置到图表并分配实例句柄(Handle)。 | -| | `material_get_graph` | ✅ | 查询图表中的所有节点句柄及其状态。 | -| **P3: 连接拓扑** | `material_connect_nodes` | ✅ | **自然连接**:建立节点间的逻辑映射(A -> B),模拟功能性嵌套。 | -| | `material_connect_pins` | ✅ | **外科连线**:在复杂拓扑下手动连接特定的输入引脚。 | -| **P4: 符号检索** | `material_search_library` | 🚧 计划中 | 快速检索 UE5 材质表达式库中的符号(Symbol)。 | -| **P5: 细节注入** | `material_set_hlsl_node_io` | ✅ | **战术细节**:编写 Custom 节点的 HLSL 代码并实时同步 IO 引脚。 | -| | `material_set_node_properties` | ✅ | **属性编辑**:设置常规节点(如 Constant, TextureSample)的内部属性值。 | -| **生命周期** | `material_compile_asset` | ✅ | 提交更改并分析 HLSL 报错。 | -| | `material_delete` | ✅ | 根据唯一句柄删除实例。 | -| **维护** | `material_get_pins` | ✅ | 内省特定节点句柄的引脚。 | - -## UMG HLSL MCP API 实现状态(新增:面向 UMG 的文本编辑闭环) - -| 命令 | 状态 | 描述 | -| ------------------- | :--: | -------------------------------------------------------------------------------------------- | -| `hlsl_set_target` | ✅ | 锁定/创建 HLSL 目标材质。校验 UI 材质域 + 单 Custom 节点拓扑;不匹配时可先返回覆写确认。 | -| `hlsl_get` | ✅ | 读取当前 HLSL 代码和结构化输入参数信息。 | -| `hlsl_set` | ✅ | 对 HLSL 与/或参数做增量更新。删除必须显式标记(`delete: true`),避免误删。 | -| `hlsl_compile` | ✅ | 编译当前 HLSL 目标并返回精简诊断信息,便于 AI 后处理。 | - -### HLSL 协议约定(UMG 垂直优化) - -- 材质被视作单一 HLSL 程序。 -- 后端约定 HLSL 返回 `float4`。 -- 输出自动连线固定为:`.rgb -> FinalColor`,`.a -> Opacity`。 -- 输入参数以结构化描述返回(如 `name`、`kind`、`source_handle`),便于 AI 学习与复用。 -- `hlsl_set` 采用“易写难删”策略:写入简单,删除必须显式声明。 - -## UMG 样式与主题 (Style & Theming) API 实现状态 (New) - -| 类别 | API 名称 | status | 描述 | -| -------- | -------------------- | :----: | --------------------------------------------- | -| **样式** | `set_widget_style` | ⏳ | 设置特定控件的详细样式(例如 FButtonStyle)。 | -| **主题** | `apply_global_theme` | ⏳ | 根据主题配置批量应用样式、字体和配色。 | -| **资源** | `style_create_asset` | ⏳ | 创建独立的 Slate 控件样式资源。 | - -## 项目状态更新 (Project Status) - -很抱歉,因为google取消了我的学生优惠,因此我空闲的时间无法推进此项目。但是不要担心,因为这迫使我使用其他平台的AI,也许能加速此插件支持其他平台的进度。具体来说,我们接下来的开发计划是在fab版中添加各种API key的接入因为我认为各位都是懂技术的,但是真正需要UMG的应该是不懂技术的美工。无论如何,如果你能在fab上购买一份付费版的UMG MCP,那就再好不过了,也许我就可以直接订阅Gemini AI进行开发了? +
+ +--- + +
+⚖️ AI Authorship & Disclaimer + +This project has been developed with significant assistance from **Gemini, an AI**. As such: +* **Experimental Nature**: This is an experimental project. Its reliability is not guaranteed. +* **Commercial Use**: Commercial use is not recommended without thorough independent validation and understanding of its limitations. +* **Disclaimer**: Use at your own risk. The developers and AI are not responsible for any consequences arising from its use. + +
+ +--- + +## UMG Widget API Status + +| Category | API Name | Status | Description | +| --------------------------- | -------------------------------- | :----: | ------------------------------------------------------------------------------------------------ | +| **Context & Attention** | `get_target_umg_asset` | ✅ | Get the current active UMG asset path. | +| | `set_target_umg_asset` | ✅ | Set or create the target UMG asset. | +| | `get_last_edited_umg_asset` | ✅ | Get the last edited UMG asset path. | +| | `get_recently_edited_umg_assets` | ✅ | Get recently edited UMG assets list. | +| **Sensing & Querying** | `get_widget_tree` | ✅ | Get children of the widget target and show them as a tree (highly token-efficient). | +| | `query_widget_properties` | ✅ | Query specific properties of a widget. | +| | `get_creatable_widget_types` | ✅ | Get all creatable widget classes. | +| | `get_widget_schema` | ✅ | Get the property schema of a widget class. | +| | `get_layout_data` | ✅ | Get screen-space layout bounding boxes. | +| | `check_widget_overlap` | Hidden | Diagnostic compatibility tool; not exposed in the default prompt surface. | +| **Actions & Modifications** | `create_widget` | ✅ | Create a new widget. | +| | `delete_widget` | ✅ | Explicitly delete a widget; requires `confirm_delete=true`. | +| | `set_widget_properties` | ✅ | Set properties of a widget (omit widget_name to target active widget; union write fashion). | +| | `reorder_widget_tree` | ✅ | Reorder existing siblings from a partial tree without creating or deleting widgets. | +| | `reparent_widget` | ✅ | Convert/move a widget while preserving children where possible; child-loss cases fail. | +| | `save_asset` | ✅ | Save the active UMG asset. | +| | `apply_layout` | ✅ | Apply bulk layout definition (HTML/JSON). | +| **Hidden Compatibility** | `export_umg_to_json` | Hidden | Full JSON export for debug/compatibility; not part of the default semantic read flow. | +| | `apply_json_to_umg` | Hidden | Compatibility bulk JSON apply; prefer `apply_layout`. | + +Notes: +- UMG writes are append/upsert style: `create_widget` creates missing widgets and `set_widget_properties` only overwrites supplied properties. +- Deletion is explicit and hardened: `delete_widget` fails unless `confirm_delete=true` is supplied. + + +## UMG Blueprint API Status (Transitional) + +Blueprint MCP is still node-shaped. It is usable for simple event wiring, but it is not the final high-density `bluecode` protocol described in [Document/BlueprintBluecodeProtocol.md](Document/BlueprintBluecodeProtocol.md). + +| Category | API Name | Status | Description | +| --------------------------- | ------------------------- | :----: | --------------------------------------------------------------------------------------------------- | +| **Context & Attention** | `set_edit_function` | ✅ | Set the current edit context (Function/Event). Supports auto-creating Custom Events. | +| | `set_cursor_node` | Partial | Low-level cursor escape hatch for branches or repair flows. Prefer `set_edit_function` + append. | +| **Sensing & Querying** | `get_function_nodes` | Partial | Transitional node readback: IDs, node names/classes, and exec flags only. | +| | `get_variables` | ✅ | Get list of member variables. | +| | `search_function_library` | ✅ | Search callable libraries (C++/BP). Supports fuzzy search. | +| **Union Writes** | `add_step(name)` | ✅ | Add executable node by name (e.g. "PrintString"). Auto-wiring and auto-layout supported. | +| | `prepare_value(name)` | ✅ | Add data node by name (e.g. "MakeLiteralString", "GetVariable"). | +| | `connect_data_to_pin` | ✅ | Connect pins precisely (supports `NodeID:PinName` format). | +| | `add_variable` | ✅ | Add or update a member variable; do not remove unspecified variables. | +| | `compile_blueprint` | ✅ | Compile and apply changes. | +| **Hidden Compatibility** | `delete_variable` | Hidden | Backend compatibility only; hidden from default MCP until deletion requires `confirm_delete=true`. | +| | `delete_node` | Hidden | Backend compatibility only; hidden from default MCP until deletion requires `confirm_delete=true`. | + +Notes: +- Current Blueprint reads are not yet semantically dense enough to answer "read any information" well. +- `bluecode` should introduce code-like read/write, append-only merge semantics, explicit `bluecode_delete(confirm_delete=true)`, and compact compile diagnostics. +- Until then, use Blueprint MCP only for narrow event wiring and verify with `compile_blueprint` plus focused readback. + +## UMG Sequencer API Status + +| Command | Status | Description | +| :------------------------------- | :----: | :--------------------------------------------------------------------------------------------------------------- | +| `set_animation_scope` | ✅ | Animation target: focus the current animation and auto-create it when missing. | +| `set_widget_scope` | ✅ | Widget target inside the current animation. | +| `get_all_animations` | ✅ | Compact animation list for the active UMG target. | +| `animation_overview` | ✅ | Returns keyframe counts, track counts, key times, and changed properties. | +| `animation_widget_properties` | ✅ | Timeline view: per-widget property changes (ignores unanimated properties). | +| `animation_time_properties` | ✅ | Time-slice view: property values at specific times (multi-time supported). | +| `animation_append_widget_tracks` | ✅ | Append/overwrite keys per widget+property (union only, no implicit deletion). | +| `animation_append_time_slice` | ✅ | Append a diff-style time slice for multiple widgets at a given time. | +| `animation_delete_widget_keys` | ✅ | Scoped delete for widget+property at specific times (`confirm_delete=true` required per Issue 15 safety policy). | +| `create_animation` | ✅ | Create or focus an animation with auto naming. | +| `delete_animation` | ✅ | Explicit whole-animation delete; requires `confirm_delete=true`. | + +Notes: +- `set_animation_scope`/`set_widget_scope` implement the target/default semantics from the protocol; names are auto-corrected (no "animal" typo) and animations auto-create when missing. +- Write paths are union/overwrite only—no implicit deletion. Use `animation_delete_widget_keys` with `confirm_delete=true` for scoped removals. +- Legacy low-level reads/writes such as `get_animation_keyframes`, `get_animation_full_data`, `set_property_keys`, `set_animation_data`, `remove_property_track`, and `remove_keys` remain backend compatibility commands but are hidden from the default MCP prompt surface. +- Responses include counts/timeline context so every default Sequencer MCP returns actionable data. + +## UMG Material API Status + +| Command | Status | Description | +| ----------------- | :----: | ---------------------------------------------------------------------------------------------------------------- | +| `hlsl_set_target` | ✅ | Lock/create the HLSL target material. New assets default to UI; pass type fields for non-UMG materials. | +| `hlsl_get` | ✅ | Read current HLSL code, structured parameters, and the semantic output contract. | +| `hlsl_set` | ✅ | Union-style write for HLSL, parameters, and extra outputs: overwrite existing items and append missing ones. | +| `hlsl_delete` | ✅ | Explicitly delete HLSL parameters or outputs with `confirm_delete=true`; add `kind` only when a name is ambiguous. | +| `hlsl_compile` | ✅ | Compile current HLSL target and return concise diagnostics for AI post-processing. | + +### HLSL Protocol Contract (UMG-Optimized) + +- Material is treated as a single HLSL program. +- Backend assumes HLSL returns `float4`. +- Output auto-wiring is semantic: UI/Post Process/Light Function/Unlit routes rgb to `EmissiveColor`; Lit Surface routes rgb to `BaseColor`; alpha only connects to `Opacity` or `OpacityMask` when needed. +- Extra material outputs use UE 5.8 Custom node `AdditionalOutputs`, so one HLSL block can drive `Roughness`, `Metallic`, `Normal`, `WorldPositionOffset`, and similar root outputs. +- Input parameters are returned as structured descriptors (`name`, `kind`, `source_handle`) for learning/replay by AI agents. +- `hlsl_set` only performs union overwrite/append operations. Deletion must use `hlsl_delete(confirm_delete=true)`. +- Low-level `material_*` graph tools are kept as a compatibility layer, but the Material ToolMode exposes the HLSL loop by default. + +## UMG Style & Theming API Status (New) + +| Category | API Name | Status | Description | +| ----------- | -------------------- | :-------: | ----------------------------------------------------------------------------- | +| **Styling** | `set_widget_style` | 🚧 Planned | Set detailed style (e.g. FButtonStyle) for a specific widget. | +| **Theming** | `apply_global_theme` | 🚧 Planned | Batch apply styles and fonts across multiple widgets based on a theme config. | +| **Assets** | `style_create_asset` | 🚧 Planned | Create a standalone Slate Widget Style asset. | + +--- + +## Developer Program + +> We notice there are many forks but few PRs — here's your invitation to change that. + +
+❓ What is the Developer Program & Why does it exist? + +We are living in the age of AI. Everyone now has the ability to build and contribute to projects with AI assistance. UMG MCP is sincerely provided free of charge for everyone to learn and use — and this should include the Fab version too. + +By joining the Developer Program and meeting the contribution criteria, **you will gain access to the private repository during your active development period**. + +
+ +
+🎁 Why is the reward a Fab version license? + +The only reason the Fab version is paid is an economic reality: if it were free, the average social return on labor would drop dramatically. Charging for it is the only mechanism to sustain development. The Fab version of UMG MCP *should* be free — but making it truly free would only force us to work harder for less. Therefore, rewarding contributors with a Fab license serves two purposes: it gives you access to the more polished version, and it gives you the ability to maintain the real, production-grade project. + +
+ +
+🛠️ How to join the UMG MCP Developer Program? + +This is admittedly a bit of a paradox — UMG MCP is designed to serve non-programmers, and programmers may not need it as much. Regardless, here are the paths to contribute: + +**Path 1 — Video Content:** +Create a video specifically about the UMG MCP **Fab version**. Reach a meaningful audience and we'll count it. + +**Path 2 — Feature Development:** +Our design philosophy is simple: *if your tool gets accepted, you're in*. Develop a feature, submit a PR, and if we merge it, you qualify. + +**Path 3 — Prompt Engineering:** +Write system prompts that help the AI more accurately identify and invoke the correct tools — even when all tools are enabled simultaneously. Precision matters here. + +**Path 4 — Purchase the Fab version:** +If you've purchased it, you already have the right to access this project. Simple as that. + +**To apply:** Send your GitHub profile to **winyunq@gmail.com** + +
diff --git a/Resources/Icon/Agent.png b/Resources/Icon/Agent.png new file mode 100644 index 0000000..7e8ba0d Binary files /dev/null and b/Resources/Icon/Agent.png differ diff --git a/Resources/Icon/Icon16.png b/Resources/Icon/Icon16.png new file mode 100644 index 0000000..63b37c5 Binary files /dev/null and b/Resources/Icon/Icon16.png differ diff --git a/Resources/Icon/layout.png b/Resources/Icon/layout.png new file mode 100644 index 0000000..4bcf74c Binary files /dev/null and b/Resources/Icon/layout.png differ diff --git a/Resources/Icon/material.png b/Resources/Icon/material.png new file mode 100644 index 0000000..426a0c9 Binary files /dev/null and b/Resources/Icon/material.png differ diff --git a/Resources/Icon/sequence.png b/Resources/Icon/sequence.png new file mode 100644 index 0000000..598d062 Binary files /dev/null and b/Resources/Icon/sequence.png differ diff --git a/Resources/Icon/widget.png b/Resources/Icon/widget.png new file mode 100644 index 0000000..58cd8dc Binary files /dev/null and b/Resources/Icon/widget.png differ diff --git a/Resources/Icon128.png b/Resources/Icon128.png new file mode 100644 index 0000000..b978dde Binary files /dev/null and b/Resources/Icon128.png differ diff --git a/UmgMcp.uplugin b/UmgMcp.uplugin index 2b8db57..80108b0 100644 --- a/UmgMcp.uplugin +++ b/UmgMcp.uplugin @@ -3,14 +3,14 @@ "Version": 1, "VersionName": "1.0", "FriendlyName": "UmgMcp", - "Description": "UmgMcp Focus: Core UMG protocol is Open-Source; Fab Edition provides 'Context Compression' and high-performance reliability.", + "Description": "Open-source MCP bridge for AI-assisted Unreal UMG authoring, inspection, and structured UI asset editing.", "Category": "Editor", "CreatedBy": "Winyunq", "CreatedByURL": "", - "DocsURL": "https://github.com/winyunq/UnrealMotionGraphicsMCP", + "DocsURL": "https://winyunq.github.io/UnrealMotionGraphicsMCP/", "MarketplaceURL": "", "SupportURL": "", - "EngineVersion": "5.6.0", + "EngineVersion": "5.8.0", "CanContainContent": true, "IsBetaVersion": false, "IsExperimentalVersion": false, @@ -26,4 +26,4 @@ } ], "Plugins": [] -} \ No newline at end of file +} diff --git a/architecture.html b/architecture.html new file mode 100644 index 0000000..cb1412f --- /dev/null +++ b/architecture.html @@ -0,0 +1,320 @@ + + + + + + Architecture — UMG MCP + + + + + + + +
+
+ +

System Architecture

+

Understand how UMG MCP connects your AI client to Unreal Engine's internals.

+
+
+ + +
+
+
+

Open Source Architecture

+

MCP Protocol bridges external AI clients to the UE5 editor in real time.

+
+
+ + + + + + + + + + + + + + + + + + + + EXTERNAL AI ZONE + + + MCP LAYER + + + UE5 ENGINE ZONE + + + + + Gemini + Google AI Studio + + + + GPT / Claude + OpenAI / Anthropic + + + + MCP Client + Claude Desktop / Cursor + + + + + + MCP Server + Python · stdio/HTTP + Tool dispatcher + + + + + + UmgMcpConfig.json + Port · Settings + + + + + + UmgMcpBridge + C++ UE5 Plugin + TCP Socket · JSON Parser + Command Router + + + + + + UE5 Editor API + UMG · Blueprint · Material · Anim + + + + + + UMG Widget + .uasset + + + + Blueprint + .uasset + + + + + + + MCP Protocol + + + TCP/JSON + + + Unreal API + + + + + + + Response: JSON result + success/error feedback + + + All operations are reversible · Undo supported + +
+
+
+ + +
+
+
+

Component Breakdown

+

Each layer of the stack explained.

+
+
+
+ Layer 1 +

AI Client Layer

+

Any MCP-compatible AI client (Claude Desktop, Cursor, custom scripts) or AI API (Gemini, GPT, Claude). The client sends natural language queries and calls MCP tools.

+
+
+ Layer 2 +

MCP Server (Python)

+

Runs as a local Python process. Exposes all UMG operations as typed MCP tools. Receives tool calls, serializes them to JSON, and sends to the UE5 bridge via TCP.

+
+
+ Layer 3 +

UmgMcpBridge (C++)

+

Native UE5 C++ plugin. Opens a TCP socket server, listens for JSON commands, routes them to the correct UE5 Unreal API calls, and returns results as JSON.

+
+
+ Layer 4 +

UE5 Asset Layer

+

The actual UMG widgets, Blueprint graphs, materials, and animations modified by the AI. All changes are live in the UE5 editor and can be undone normally.

+
+
+
+
+ + +
+
+
+ +

Commercial Multi-Agent Architecture

+

The commercial version replaces the Python layer with a native C++ multi-agent orchestration system.

+
+
+ + + + User Input + Natural language · API key configured + + + + C++ Agent Runtime + Orchestrator · Task Planner · Context Manager + No Python dependency — pure native + + + + Layout Agent + Widget structure + & positioning + + + Blueprint Agent + Logic, events + & bindings + + + Material Agent + Visual FX + & HLSL shaders + + + Anim Agent + Keyframes + & sequencer + + + Style Agent + Theme & design + system (Phase 2) + + + + UE5 Editor API — Shared by all agents + + + + + + + + + + + + + + + + Parallel dispatch + +
+
+
+ + +
+
+
+

Data Flow

+

A single user request, traced through the entire stack.

+
+
+
+
1
+
+

User sends natural language

+

e.g. "Create a health bar at the top left, red fill, white background, 200px wide"

+
+
+
+
2
+
+

AI client processes & selects tools

+

The LLM determines which MCP tools are needed: create_widget, set_widget_property, etc.

+
+
+
+
3
+
+

MCP Server routes the call

+

The tool call is received, validated, serialized to JSON, and forwarded over TCP to the UE5 plugin on localhost:19202.

+
+
+
+
4
+
+

UmgMcpBridge executes in UE5

+

The C++ plugin receives the command, calls the appropriate Unreal Engine API (e.g. UWidgetBlueprint::AddWidget), and returns a JSON success/error response.

+
+
+
+
5
+
+

Result feeds back to AI

+

The AI receives the result, confirms success, and can immediately continue with the next operation — enabling multi-step UI construction in a single conversation.

+
+
+
+
+
+ +
+ + + diff --git a/assets/css/main.css b/assets/css/main.css new file mode 100644 index 0000000..084d20b --- /dev/null +++ b/assets/css/main.css @@ -0,0 +1,1002 @@ +/* ========================================================= + UMG MCP — Main Stylesheet + Dark tech theme · Purple/Blue/Cyan palette + ========================================================= */ + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;900&display=swap'); + +/* ── Variables ─────────────────────────────────────────── */ +:root { + --bg: #0a0a0f; + --surface: #12121a; + --card: #1a1a2e; + --card-alt: #16213e; + --primary: #7c3aed; + --primary-light: #9d5cf6; + --secondary: #2563eb; + --accent: #06b6d4; + --accent2: #10b981; + --text: #e2e8f0; + --muted: #94a3b8; + --border: rgba(124,58,237,0.25); + --border2: rgba(255,255,255,0.07); + --gradient: linear-gradient(135deg, #7c3aed, #2563eb); + --gradient2: linear-gradient(135deg, #2563eb, #06b6d4); + --glow: 0 0 40px rgba(124,58,237,0.3); + --radius: 12px; + --radius-lg: 20px; + --shadow: 0 4px 24px rgba(0,0,0,0.4); + --shadow-lg: 0 8px 48px rgba(0,0,0,0.6); + --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + --mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace; + --nav-h: 64px; + --transition: 0.25s cubic-bezier(0.4,0,0.2,1); +} + +/* ── Reset ─────────────────────────────────────────────── */ +*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } +html { scroll-behavior: smooth; font-size: 16px; } +body { + font-family: var(--font); + background: var(--bg); + color: var(--text); + line-height: 1.6; + -webkit-font-smoothing: antialiased; + overflow-x: hidden; +} +img, video { max-width: 100%; display: block; } +a { color: var(--accent); text-decoration: none; transition: color var(--transition); } +a:hover { color: var(--primary-light); } +ul { list-style: none; } +button { cursor: pointer; font-family: var(--font); border: none; } + +/* ── Typography ────────────────────────────────────────── */ +h1, h2, h3, h4, h5 { font-weight: 700; line-height: 1.2; color: var(--text); } +h1 { font-size: clamp(2.2rem, 5vw, 4rem); font-weight: 900; } +h2 { font-size: clamp(1.6rem, 3.5vw, 2.6rem); } +h3 { font-size: clamp(1.2rem, 2.5vw, 1.6rem); } +h4 { font-size: 1.15rem; } +p { color: var(--muted); line-height: 1.75; } + +.gradient-text { + background: var(--gradient); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} +.accent-text { color: var(--accent); } +.primary-text { color: var(--primary-light); } + +/* ── Layout ────────────────────────────────────────────── */ +.container { max-width: 1200px; margin: 0 auto; padding: 0 24px; } +.container-sm { max-width: 840px; margin: 0 auto; padding: 0 24px; } +.container-lg { max-width: 1400px; margin: 0 auto; padding: 0 24px; } + +.section { padding: 80px 0; } +.section-sm { padding: 48px 0; } +.section-lg { padding: 120px 0; } + +.section-header { text-align: center; margin-bottom: 60px; } +.section-header p { max-width: 600px; margin: 16px auto 0; font-size: 1.1rem; } +.section-label { + display: inline-block; + font-size: 0.75rem; + font-weight: 600; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--accent); + background: rgba(6,182,212,0.1); + border: 1px solid rgba(6,182,212,0.25); + border-radius: 20px; + padding: 4px 14px; + margin-bottom: 16px; +} + +/* ── Navbar ────────────────────────────────────────────── */ +#main-nav { + position: fixed; + top: 0; left: 0; right: 0; + z-index: 1000; + height: var(--nav-h); + background: rgba(10,10,15,0.85); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border-bottom: 1px solid var(--border2); + transition: background var(--transition), box-shadow var(--transition); +} +#main-nav.scrolled { background: rgba(10,10,15,0.97); box-shadow: var(--shadow); } +.nav-inner { + display: flex; + align-items: center; + height: 100%; + gap: 32px; +} +.nav-logo { + display: flex; + align-items: center; + gap: 10px; + font-weight: 700; + font-size: 1.1rem; + color: var(--text); + white-space: nowrap; + text-decoration: none; + flex-shrink: 0; +} +.nav-logo svg { width: 28px; height: 28px; } +.nav-logo span { background: var(--gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } + +.nav-links { + display: flex; + align-items: center; + gap: 4px; + flex: 1; +} +.nav-links a { + color: var(--muted); + font-size: 0.9rem; + font-weight: 500; + padding: 6px 12px; + border-radius: 8px; + transition: color var(--transition), background var(--transition); +} +.nav-links a:hover, .nav-links a.active { color: var(--text); background: rgba(255,255,255,0.07); } + +.nav-actions { + display: flex; + align-items: center; + gap: 12px; + margin-left: auto; + flex-shrink: 0; +} + +.lang-switcher { + display: flex; + background: var(--card); + border: 1px solid var(--border2); + border-radius: 8px; + overflow: hidden; +} +.lang-switcher button { + background: none; + color: var(--muted); + font-size: 0.8rem; + font-weight: 600; + padding: 5px 12px; + transition: all var(--transition); +} +.lang-switcher button.active { + background: var(--primary); + color: #fff; +} +.lang-switcher button:hover:not(.active) { color: var(--text); background: rgba(255,255,255,0.05); } + +.nav-cta { + background: var(--gradient); + color: #fff !important; + font-size: 0.85rem; + font-weight: 600; + padding: 8px 18px; + border-radius: 8px; + transition: opacity var(--transition), transform var(--transition); +} +.nav-cta:hover { opacity: 0.9; transform: translateY(-1px); } + +.nav-toggle { + display: none; + flex-direction: column; + gap: 5px; + background: none; + padding: 6px; + border-radius: 8px; +} +.nav-toggle span { + display: block; + width: 22px; + height: 2px; + background: var(--text); + border-radius: 2px; + transition: all 0.3s; +} + +/* ── Hero ──────────────────────────────────────────────── */ +.hero { + min-height: 100vh; + display: flex; + align-items: center; + position: relative; + overflow: hidden; + padding-top: var(--nav-h); +} + +.hero-bg { + position: absolute; + inset: 0; + z-index: 0; +} +.hero-gradient { + position: absolute; + inset: 0; + background: radial-gradient(ellipse 80% 60% at 50% 40%, rgba(124,58,237,0.15) 0%, transparent 70%), + radial-gradient(ellipse 50% 40% at 80% 20%, rgba(37,99,235,0.1) 0%, transparent 60%), + radial-gradient(ellipse 40% 30% at 20% 80%, rgba(6,182,212,0.08) 0%, transparent 60%); +} +.hero-grid { + position: absolute; + inset: 0; + background-image: + linear-gradient(rgba(124,58,237,0.04) 1px, transparent 1px), + linear-gradient(90deg, rgba(124,58,237,0.04) 1px, transparent 1px); + background-size: 60px 60px; + mask-image: radial-gradient(ellipse 80% 80% at 50% 50%, black, transparent); +} + +/* Floating particles */ +.hero-particles { position: absolute; inset: 0; pointer-events: none; } +.particle { + position: absolute; + border-radius: 50%; + opacity: 0.6; + animation: float linear infinite; +} + +@keyframes float { + 0% { transform: translateY(100vh) scale(0); opacity: 0; } + 5% { opacity: 0.6; } + 95% { opacity: 0.6; } + 100% { transform: translateY(-20px) scale(1); opacity: 0; } +} + +.hero-content { + position: relative; + z-index: 1; + text-align: center; + max-width: 900px; + margin: 0 auto; +} +.hero-badge { + display: inline-flex; + align-items: center; + gap: 8px; + background: rgba(124,58,237,0.15); + border: 1px solid rgba(124,58,237,0.35); + border-radius: 24px; + padding: 6px 18px; + font-size: 0.82rem; + font-weight: 600; + color: var(--primary-light); + margin-bottom: 28px; + animation: fadeInDown 0.6s ease; +} +.hero-badge .dot { + width: 7px; height: 7px; + background: var(--accent2); + border-radius: 50%; + animation: pulse 2s infinite; +} +@keyframes pulse { 0%,100%{opacity:1;transform:scale(1)} 50%{opacity:0.5;transform:scale(0.8)} } + +.hero h1 { + margin-bottom: 24px; + animation: fadeInUp 0.7s ease 0.1s both; +} +.typing-container { + display: inline-block; + position: relative; +} +.typing-text { border-right: 3px solid var(--accent); white-space: nowrap; overflow: hidden; } +@keyframes blinkCaret { 0%,100%{border-color:var(--accent)} 50%{border-color:transparent} } + +.hero-subtitle { + font-size: clamp(1rem, 2vw, 1.25rem); + color: var(--muted); + max-width: 680px; + margin: 0 auto 40px; + animation: fadeInUp 0.7s ease 0.2s both; +} + +.hero-cta { + display: flex; + gap: 16px; + justify-content: center; + flex-wrap: wrap; + animation: fadeInUp 0.7s ease 0.3s both; +} + +/* ── Buttons ───────────────────────────────────────────── */ +.btn { + display: inline-flex; + align-items: center; + gap: 8px; + font-size: 0.95rem; + font-weight: 600; + padding: 12px 28px; + border-radius: 10px; + transition: all var(--transition); + white-space: nowrap; + text-decoration: none; +} +.btn-primary { + background: var(--gradient); + color: #fff; + box-shadow: 0 4px 20px rgba(124,58,237,0.4); +} +.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 8px 30px rgba(124,58,237,0.5); color: #fff; } +.btn-secondary { + background: transparent; + color: var(--text); + border: 1px solid var(--border2); +} +.btn-secondary:hover { background: rgba(255,255,255,0.07); transform: translateY(-2px); color: var(--text); } +.btn-accent { + background: linear-gradient(135deg, var(--accent), var(--secondary)); + color: #fff; + box-shadow: 0 4px 20px rgba(6,182,212,0.35); +} +.btn-accent:hover { transform: translateY(-2px); box-shadow: 0 8px 30px rgba(6,182,212,0.45); color: #fff; } +.btn-ghost { background: none; color: var(--muted); border: 1px solid var(--border2); } +.btn-ghost:hover { color: var(--text); background: rgba(255,255,255,0.05); } +.btn-sm { font-size: 0.82rem; padding: 8px 18px; } +.btn-lg { font-size: 1.05rem; padding: 15px 36px; } + +/* ── Stats bar ─────────────────────────────────────────── */ +.stats-bar { + display: flex; + justify-content: center; + gap: 48px; + flex-wrap: wrap; + padding: 32px 0; + border-top: 1px solid var(--border2); + border-bottom: 1px solid var(--border2); + margin-top: 64px; + animation: fadeInUp 0.7s ease 0.4s both; +} +.stat-item { text-align: center; } +.stat-number { + font-size: 2rem; + font-weight: 900; + background: var(--gradient); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + display: block; +} +.stat-label { font-size: 0.8rem; color: var(--muted); font-weight: 500; margin-top: 4px; } + +/* ── Cards ─────────────────────────────────────────────── */ +.card { + background: var(--card); + border: 1px solid var(--border2); + border-radius: var(--radius-lg); + padding: 32px; + transition: transform var(--transition), border-color var(--transition), box-shadow var(--transition); +} +.card:hover { + transform: translateY(-4px); + border-color: var(--border); + box-shadow: var(--glow); +} +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 24px; +} +.card-icon { + width: 52px; height: 52px; + background: rgba(124,58,237,0.15); + border: 1px solid rgba(124,58,237,0.25); + border-radius: 14px; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.4rem; + margin-bottom: 20px; +} +.card h3 { margin-bottom: 10px; font-size: 1.15rem; } +.card p { font-size: 0.92rem; } + +.card-accent { border-color: rgba(6,182,212,0.3); } +.card-accent .card-icon { background: rgba(6,182,212,0.1); border-color: rgba(6,182,212,0.25); } +.card-green { border-color: rgba(16,185,129,0.3); } +.card-green .card-icon { background: rgba(16,185,129,0.1); border-color: rgba(16,185,129,0.25); } + +/* Reveal animation */ +.reveal { + opacity: 0; + transform: translateY(30px); + transition: opacity 0.6s ease, transform 0.6s ease; +} +.reveal.visible { opacity: 1; transform: translateY(0); } +.reveal-delay-1 { transition-delay: 0.1s; } +.reveal-delay-2 { transition-delay: 0.2s; } +.reveal-delay-3 { transition-delay: 0.3s; } +.reveal-delay-4 { transition-delay: 0.4s; } + +/* ── Feature grid ──────────────────────────────────────── */ +.feature-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); + gap: 2px; + background: var(--border2); + border-radius: var(--radius-lg); + overflow: hidden; +} +.feature-item { + background: var(--card); + padding: 36px 32px; + transition: background var(--transition); +} +.feature-item:hover { background: var(--card-alt); } +.feature-item .fi-icon { + font-size: 2rem; + margin-bottom: 16px; +} + +/* ── Comparison table ──────────────────────────────────── */ +.compare-wrap { overflow-x: auto; } +.compare-table { + width: 100%; + border-collapse: collapse; + font-size: 0.92rem; +} +.compare-table th { + padding: 20px 24px; + text-align: left; + background: var(--card); + font-size: 1rem; + font-weight: 700; +} +.compare-table th:first-child { border-radius: var(--radius) 0 0 0; } +.compare-table th:last-child { border-radius: 0 var(--radius) 0 0; } +.compare-table th.col-oss { color: var(--accent); } +.compare-table th.col-fab { color: var(--primary-light); background: rgba(124,58,237,0.12); } +.compare-table td { + padding: 14px 24px; + border-bottom: 1px solid var(--border2); + color: var(--muted); +} +.compare-table tr td:last-child { background: rgba(124,58,237,0.04); } +.compare-table tr:hover td { background: rgba(255,255,255,0.03); } +.compare-table tr:hover td:last-child { background: rgba(124,58,237,0.08); } +.check { color: var(--accent2); font-size: 1rem; } +.cross { color: #f87171; font-size: 1rem; } +.partial { color: #fbbf24; font-size: 0.85rem; } + +/* ── Code block ────────────────────────────────────────── */ +.code-block { + background: #0d1117; + border: 1px solid var(--border2); + border-radius: var(--radius); + padding: 24px; + overflow-x: auto; + font-family: var(--mono); + font-size: 0.85rem; + line-height: 1.6; + position: relative; +} +.code-block pre { color: var(--text); white-space: pre; } +.code-lang { + position: absolute; + top: 12px; right: 16px; + font-size: 0.7rem; + font-weight: 600; + color: var(--muted); + text-transform: uppercase; + letter-spacing: 0.1em; +} +.tok-kw { color: #ff79c6; } +.tok-str { color: #50fa7b; } +.tok-fn { color: #8be9fd; } +.tok-cm { color: #6272a4; } +.tok-num { color: #bd93f9; } + +/* ── Tabs ──────────────────────────────────────────────── */ +.tabs-nav { + display: flex; + gap: 4px; + background: var(--surface); + border: 1px solid var(--border2); + border-radius: 12px; + padding: 4px; + width: fit-content; + margin: 0 auto 40px; +} +.tab-btn { + background: none; + color: var(--muted); + font-size: 0.9rem; + font-weight: 600; + padding: 10px 24px; + border-radius: 9px; + transition: all var(--transition); +} +.tab-btn.active { background: var(--gradient); color: #fff; } +.tab-btn:hover:not(.active) { color: var(--text); background: rgba(255,255,255,0.05); } + +.tab-pane { display: none; } +.tab-pane.active { display: block; animation: fadeIn 0.3s ease; } +@keyframes fadeIn { from{opacity:0;transform:translateY(8px)} to{opacity:1;transform:translateY(0)} } + +/* ── Steps ─────────────────────────────────────────────── */ +.steps { display: flex; flex-direction: column; gap: 0; } +.step { + display: flex; + gap: 24px; + padding: 32px 0; + border-bottom: 1px solid var(--border2); + position: relative; +} +.step:last-child { border-bottom: none; } +.step-num { + width: 48px; height: 48px; + flex-shrink: 0; + background: var(--gradient); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-weight: 900; + font-size: 1.1rem; + color: #fff; + box-shadow: 0 4px 16px rgba(124,58,237,0.4); + z-index: 1; +} +.step::before { + content: ''; + position: absolute; + left: 23px; + top: 80px; + bottom: -32px; + width: 2px; + background: linear-gradient(to bottom, var(--primary), transparent); +} +.step:last-child::before { display: none; } +.step-content { flex: 1; padding-top: 8px; } +.step-content h4 { margin-bottom: 8px; } + +/* ── Timeline / Roadmap ────────────────────────────────── */ +.timeline { position: relative; padding: 20px 0; } +.timeline::before { + content: ''; + position: absolute; + left: 50%; + transform: translateX(-50%); + top: 0; bottom: 0; + width: 2px; + background: linear-gradient(to bottom, var(--primary), var(--secondary), var(--accent), rgba(6,182,212,0.1)); +} +.timeline-item { + display: flex; + justify-content: flex-end; + padding-right: calc(50% + 40px); + margin-bottom: 60px; + position: relative; +} +.timeline-item:nth-child(even) { + justify-content: flex-start; + padding-right: 0; + padding-left: calc(50% + 40px); +} +.timeline-dot { + position: absolute; + left: 50%; + transform: translateX(-50%); + top: 20px; + width: 16px; height: 16px; + border-radius: 50%; + border: 3px solid var(--bg); + z-index: 1; +} +.timeline-dot.released { background: var(--accent2); box-shadow: 0 0 12px rgba(16,185,129,0.6); } +.timeline-dot.in-progress { background: var(--accent); box-shadow: 0 0 12px rgba(6,182,212,0.6); animation: pulse 2s infinite; } +.timeline-dot.planned { background: var(--primary); box-shadow: 0 0 12px rgba(124,58,237,0.5); } +.timeline-dot.vision { background: var(--muted); } + +.timeline-card { + background: var(--card); + border: 1px solid var(--border2); + border-radius: var(--radius-lg); + padding: 28px; + max-width: 440px; + width: 100%; + transition: transform var(--transition), border-color var(--transition); +} +.timeline-card:hover { transform: translateY(-3px); border-color: var(--border); } +.timeline-phase { + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.1em; + text-transform: uppercase; + margin-bottom: 8px; +} +.phase-released { color: var(--accent2); } +.phase-in-progress { color: var(--accent); } +.phase-planned { color: var(--primary-light); } +.phase-vision { color: var(--muted); } + +.timeline-card h3 { font-size: 1.1rem; margin-bottom: 12px; } +.timeline-card ul { display: flex; flex-direction: column; gap: 6px; } +.timeline-card li { + font-size: 0.87rem; + color: var(--muted); + padding-left: 16px; + position: relative; +} +.timeline-card li::before { + content: '→'; + position: absolute; + left: 0; + color: var(--primary-light); + font-size: 0.75rem; + top: 1px; +} + +/* ── SVG Diagrams ──────────────────────────────────────── */ +.diagram-wrap { + background: var(--surface); + border: 1px solid var(--border2); + border-radius: var(--radius-lg); + padding: 48px 32px; + overflow: hidden; +} +.arch-svg { width: 100%; max-width: 800px; display: block; margin: 0 auto; } + +/* animated stroke */ +.svg-flow-line { + stroke-dasharray: 300; + stroke-dashoffset: 300; + transition: stroke-dashoffset 1.5s ease; +} +.svg-flow-line.animated { stroke-dashoffset: 0; } +.svg-flow-arrow { + opacity: 0; + transition: opacity 0.5s ease 1.2s; +} +.svg-flow-arrow.animated { opacity: 1; } + +/* animated data packet */ +.data-packet { + animation: movePacket 3s linear infinite; +} +@keyframes movePacket { + 0% { offset-distance: 0%; opacity: 1; } + 90% { opacity: 1; } + 100% { offset-distance: 100%; opacity: 0; } +} + +/* ── Video embeds ──────────────────────────────────────── */ +.video-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; } +.video-card { background: var(--card); border: 1px solid var(--border2); border-radius: var(--radius-lg); overflow: hidden; } +.video-card iframe { width: 100%; aspect-ratio: 16/9; display: block; border: none; } +.video-card-info { padding: 20px; } +.video-card-info h4 { margin-bottom: 6px; } +.video-card-info p { font-size: 0.85rem; } + +/* ── CTA Section ───────────────────────────────────────── */ +.cta-section { + text-align: center; + background: radial-gradient(ellipse 80% 100% at 50% 50%, rgba(124,58,237,0.12), transparent); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + padding: 80px 40px; + position: relative; + overflow: hidden; +} +.cta-section::before { + content: ''; + position: absolute; + inset: -2px; + background: var(--gradient); + border-radius: var(--radius-lg); + z-index: -1; + opacity: 0.15; +} +.cta-section h2 { margin-bottom: 16px; } +.cta-section p { max-width: 500px; margin: 0 auto 32px; } +.cta-buttons { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; } + +/* ── Badge / Tag ───────────────────────────────────────── */ +.badge { + display: inline-flex; + align-items: center; + gap: 5px; + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + padding: 3px 10px; + border-radius: 6px; +} +.badge-purple { background: rgba(124,58,237,0.15); color: var(--primary-light); border: 1px solid rgba(124,58,237,0.3); } +.badge-cyan { background: rgba(6,182,212,0.12); color: var(--accent); border: 1px solid rgba(6,182,212,0.25); } +.badge-green { background: rgba(16,185,129,0.12); color: var(--accent2); border: 1px solid rgba(16,185,129,0.25); } +.badge-blue { background: rgba(37,99,235,0.15); color: #60a5fa; border: 1px solid rgba(37,99,235,0.3); } +.badge-yellow { background: rgba(251,191,36,0.1); color: #fbbf24; border: 1px solid rgba(251,191,36,0.25); } + +/* ── Highlight box ─────────────────────────────────────── */ +.highlight-box { + background: rgba(124,58,237,0.08); + border: 1px solid rgba(124,58,237,0.2); + border-left: 4px solid var(--primary); + border-radius: 0 var(--radius) var(--radius) 0; + padding: 20px 24px; + margin: 24px 0; +} +.highlight-box.accent { border-left-color: var(--accent); background: rgba(6,182,212,0.06); border-color: rgba(6,182,212,0.2); } +.highlight-box.green { border-left-color: var(--accent2); background: rgba(16,185,129,0.06); border-color: rgba(16,185,129,0.2); } + +/* ── Page hero (inner pages) ───────────────────────────── */ +.page-hero { + padding: 120px 0 60px; + text-align: center; + position: relative; + overflow: hidden; +} +.page-hero::before { + content: ''; + position: absolute; + inset: 0; + background: radial-gradient(ellipse 70% 60% at 50% 30%, rgba(124,58,237,0.1) 0%, transparent 70%); + pointer-events: none; +} +.page-hero .container { position: relative; z-index: 1; } + +/* ── FAQ ───────────────────────────────────────────────── */ +.faq-list { display: flex; flex-direction: column; gap: 12px; } +.faq-item { + background: var(--card); + border: 1px solid var(--border2); + border-radius: var(--radius); + overflow: hidden; +} +.faq-question { + width: 100%; + background: none; + color: var(--text); + text-align: left; + padding: 20px 24px; + font-size: 0.97rem; + font-weight: 600; + display: flex; + justify-content: space-between; + align-items: center; + gap: 16px; + transition: background var(--transition); +} +.faq-question:hover { background: rgba(255,255,255,0.03); } +.faq-question.open { color: var(--primary-light); } +.faq-chevron { transition: transform 0.3s; flex-shrink: 0; font-size: 0.7rem; color: var(--muted); } +.faq-question.open .faq-chevron { transform: rotate(180deg); } +.faq-answer { + max-height: 0; + overflow: hidden; + transition: max-height 0.4s ease, padding 0.4s ease; + padding: 0 24px; +} +.faq-answer.open { max-height: 400px; padding: 0 24px 20px; } +.faq-answer p { font-size: 0.92rem; } + +/* ── Footer ────────────────────────────────────────────── */ +#main-footer { + background: var(--surface); + border-top: 1px solid var(--border2); + padding: 60px 0 32px; + margin-top: 80px; +} +.footer-grid { + display: grid; + grid-template-columns: 2fr repeat(3, 1fr); + gap: 48px; + margin-bottom: 48px; +} +.footer-brand p { font-size: 0.88rem; margin-top: 14px; max-width: 280px; } +.footer-col h4 { font-size: 0.82rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin-bottom: 16px; } +.footer-col ul { display: flex; flex-direction: column; gap: 10px; } +.footer-col a { font-size: 0.88rem; color: var(--muted); } +.footer-col a:hover { color: var(--text); } +.footer-bottom { + border-top: 1px solid var(--border2); + padding-top: 24px; + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 12px; + font-size: 0.82rem; + color: var(--muted); +} + +/* ── Utility ───────────────────────────────────────────── */ +.text-center { text-align: center; } +.text-right { text-align: right; } +.mt-0 { margin-top: 0 !important; } +.mt-8 { margin-top: 8px; } +.mt-16 { margin-top: 16px; } +.mt-24 { margin-top: 24px; } +.mt-32 { margin-top: 32px; } +.mt-48 { margin-top: 48px; } +.mt-64 { margin-top: 64px; } +.mb-8 { margin-bottom: 8px; } +.mb-16 { margin-bottom: 16px; } +.mb-24 { margin-bottom: 24px; } +.mb-32 { margin-bottom: 32px; } +.mb-48 { margin-bottom: 48px; } +.flex { display: flex; } +.flex-center { display: flex; align-items: center; justify-content: center; } +.gap-8 { gap: 8px; } +.gap-16 { gap: 16px; } +.gap-24 { gap: 24px; } +.gap-32 { gap: 32px; } +.w-full { width: 100%; } +.divider { border: none; border-top: 1px solid var(--border2); margin: 48px 0; } +.sr-only { position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0; } + +/* ── Animations ────────────────────────────────────────── */ +@keyframes fadeInDown { from{opacity:0;transform:translateY(-16px)} to{opacity:1;transform:translateY(0)} } +@keyframes fadeInUp { from{opacity:0;transform:translateY(24px)} to{opacity:1;transform:translateY(0)} } +@keyframes shimmer { + 0% { background-position: -200% center; } + 100% { background-position: 200% center; } +} +.shimmer-text { + background: linear-gradient(90deg, var(--text) 25%, var(--primary-light) 50%, var(--text) 75%); + background-size: 200%; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + animation: shimmer 4s linear infinite; +} + +/* ── Glow cards (feature showcase) ────────────────────────*/ +.glow-card { + position: relative; + background: var(--card); + border: 1px solid var(--border2); + border-radius: var(--radius-lg); + padding: 36px; + overflow: hidden; +} +.glow-card::after { + content: ''; + position: absolute; + inset: 0; + background: radial-gradient(circle 200px at var(--mx,50%) var(--my,50%), rgba(124,58,237,0.1), transparent 70%); + pointer-events: none; + opacity: 0; + transition: opacity 0.3s; +} +.glow-card:hover::after { opacity: 1; } + +/* ── API category ──────────────────────────────────────── */ +.api-category { margin-bottom: 40px; } +.api-category-header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 16px; + padding-bottom: 12px; + border-bottom: 1px solid var(--border2); +} +.api-category-header h3 { font-size: 1rem; } +.api-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; } +.api-chip { + background: var(--surface); + border: 1px solid var(--border2); + border-radius: 8px; + padding: 10px 16px; + font-size: 0.82rem; + color: var(--muted); + font-family: var(--mono); + transition: all var(--transition); +} +.api-chip:hover { border-color: var(--primary); color: var(--text); background: rgba(124,58,237,0.08); } + +/* ── Two-col layout ────────────────────────────────────── */ +.two-col { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 64px; + align-items: center; +} +.two-col.reverse { direction: rtl; } +.two-col.reverse > * { direction: ltr; } + +/* ── Responsive ────────────────────────────────────────── */ +@media (max-width: 1024px) { + .footer-grid { grid-template-columns: 1fr 1fr; } + .two-col { grid-template-columns: 1fr; gap: 40px; } + .two-col.reverse { direction: ltr; } + .timeline::before { left: 20px; transform: none; } + .timeline-item { justify-content: flex-start; padding-right: 0; padding-left: 60px; } + .timeline-item:nth-child(even) { justify-content: flex-start; padding-left: 60px; padding-right: 0; } + .timeline-dot { left: 20px; transform: none; } +} + +@media (max-width: 768px) { + :root { --nav-h: 56px; } + .nav-links, .nav-actions .nav-cta { display: none; } + .nav-toggle { display: flex; } + .nav-inner { justify-content: space-between; } + + /* Mobile menu */ + .nav-mobile { + display: none; + position: fixed; + top: var(--nav-h); + left: 0; right: 0; + background: rgba(10,10,15,0.98); + backdrop-filter: blur(20px); + border-bottom: 1px solid var(--border2); + padding: 16px 24px 24px; + flex-direction: column; + gap: 4px; + z-index: 999; + } + .nav-mobile.open { display: flex; } + .nav-mobile a { + color: var(--muted); + font-size: 0.95rem; + font-weight: 500; + padding: 12px 16px; + border-radius: 8px; + display: block; + } + .nav-mobile a:hover { color: var(--text); background: rgba(255,255,255,0.05); } + .nav-mobile .mobile-actions { + display: flex; + gap: 12px; + margin-top: 16px; + padding-top: 16px; + border-top: 1px solid var(--border2); + } + + .section { padding: 60px 0; } + .section-lg { padding: 80px 0; } + .stats-bar { gap: 24px; } + .footer-grid { grid-template-columns: 1fr; gap: 32px; } + .footer-bottom { flex-direction: column; text-align: center; } + .card-grid { grid-template-columns: 1fr; } + .cta-section { padding: 48px 24px; } + .tabs-nav { width: 100%; } + .tab-btn { flex: 1; padding: 10px 12px; font-size: 0.82rem; } + + .compare-table th, .compare-table td { padding: 12px 16px; font-size: 0.82rem; } +} + +@media (max-width: 480px) { + .hero-cta { flex-direction: column; align-items: center; } + .hero-cta .btn { width: 100%; justify-content: center; } + .btn-lg { padding: 14px 28px; } + .cta-buttons { flex-direction: column; align-items: center; } + .cta-buttons .btn { width: 100%; justify-content: center; } +} + +/* ── Page-specific: Commercial ─────────────────────────── */ +.no-python-hero { + text-align: center; + padding: 120px 0 80px; + position: relative; + overflow: hidden; +} +.no-python-hero::before { + content: ''; + position: absolute; + inset: 0; + background: radial-gradient(ellipse 80% 60% at 50% 40%, rgba(124,58,237,0.18) 0%, transparent 70%); +} +.big-tag { + font-size: clamp(1rem, 2.5vw, 1.3rem); + font-weight: 700; + color: var(--accent); + letter-spacing: 0.05em; + margin-bottom: 16px; + display: block; +} + +/* ── Scrollbar ─────────────────────────────────────────── */ +/* Firefox scrollbar */ +html { scrollbar-color: rgba(124,58,237,0.4) var(--bg); scrollbar-width: thin; } +/* WebKit scrollbar */ +::-webkit-scrollbar { width: 8px; height: 8px; } +::-webkit-scrollbar-track { background: var(--bg); } +::-webkit-scrollbar-thumb { background: rgba(124,58,237,0.4); border-radius: 4px; } +::-webkit-scrollbar-thumb:hover { background: rgba(124,58,237,0.6); } diff --git a/assets/i18n/en.json b/assets/i18n/en.json new file mode 100644 index 0000000..2432fca --- /dev/null +++ b/assets/i18n/en.json @@ -0,0 +1,172 @@ +{ + "nav.home": "Home", + "nav.features": "Features", + "nav.architecture": "Architecture", + "nav.workflow": "Workflow", + "nav.roadmap": "Roadmap", + "nav.docs": "Get Started", + "nav.commercial": "Commercial", + "nav.cta": "Optional Fab package →", + + "footer.brand.desc": "The first MCP plugin fully focused on UE5 UMG. AI-powered UI creation with zero friction.", + "footer.product": "Product", + "footer.product.features": "Features", + "footer.product.commercial": "Fab Package", + "footer.product.roadmap": "Roadmap", + "footer.product.changelog": "Changelog", + "footer.resources": "Resources", + "footer.resources.docs": "Get Started", + "footer.resources.architecture": "Architecture", + "footer.resources.workflow": "Workflow", + "footer.resources.github": "GitHub", + "footer.community": "Community", + "footer.community.issues": "Report Issue", + "footer.community.fab": "Fab Marketplace", + "footer.community.discussions": "Discussions", + "footer.bottom.copy": "© 2025 UMG MCP. Open source under MIT License.", + "footer.bottom.oss": "Open Source", + "footer.bottom.fab": "Fab Version", + + "hero.badge": "Open-source UMG MCP for Unreal Engine", + "hero.headline1": "The AI That", + "hero.headline2": "Speaks UMG", + "hero.subtitle": "Native UE5 UMG AI editor — just describe what you want, watch it build your interface in real time.", + "hero.cta.github": "Get Started Free", + "hero.cta.fab": "Optional Fab package →", + "hero.stat.apis": "APIs", + "hero.stat.apis.label": "MCP Tools", + "hero.stat.categories": "Categories", + "hero.stat.categories.label": "Widget / BP / Anim / Material / HLSL", + "hero.stat.python": "Python", + "hero.stat.python.label": "Python bridge documented", + "hero.stat.agents": "Multi-Agent", + "hero.stat.agents.label": "Structured editor tools", + + "index.features.label": "Core Capabilities", + "index.features.title": "AI That Understands UMG", + "index.features.subtitle": "From simple button placement to complex blueprint logic — describe it, and the AI builds it.", + "index.feat1.title": "Conversational UI Creation", + "index.feat1.desc": "Talk to your AI in natural language. It reads your intent and directly creates, modifies, or arranges UMG widgets without you touching a single property panel.", + "index.feat2.title": "Blueprint Logic Generation", + "index.feat2.desc": "Describe interactions and behaviors. The AI generates Blueprint nodes, sets variable bindings, creates animation triggers, and wires up your UI logic.", + "index.feat3.title": "Material & HLSL Editing", + "index.feat3.desc": "Ask for visual effects, shaders, or dynamic materials. The AI creates or modifies UE5 materials and even writes HLSL code for custom shader nodes.", + "index.feat4.title": "Animation & Sequencer", + "index.feat4.desc": "Bring your UI to life. Describe entrance animations, idle loops, or state transitions — the AI sets keyframes and configures UMG animation sequences.", + + "index.compare.label": "Two Versions", + "index.compare.title": "Open Source and Fab Package", + "index.compare.subtitle": "The GitHub repository is the canonical public project; Fab is an optional packaged distribution.", + "index.compare.feature": "Feature", + "index.compare.oss": "Open Source (GitHub)", + "index.compare.fab": "Fab package", + "index.compare.core_api": "Core Widget API (40+ tools)", + "index.compare.blueprint": "Blueprint Editing", + "index.compare.anim": "Animation/Sequencer API", + "index.compare.material": "Material & HLSL API", + "index.compare.python_server": "External Python MCP server", + "index.compare.chat_panel": "In-editor ChatWithUnreal panel", + "index.compare.approval": "FabServer approval queue", + "index.compare.providers": "Provider settings UI", + "index.compare.litert": "Local LiteRT-LM runtime", + "index.compare.python": "Requires Python", + "index.compare.install": "One-click UE5 install", + "index.compare.multiagent": "Multi-Agent AI", + "index.compare.support": "Priority Support", + "index.compare.updates": "Commercial Updates", + "index.compare.license": "License", + "index.compare.license.oss": "MIT", + "index.compare.license.fab": "Commercial", + + "index.videos.label": "See It in Action", + "index.videos.title": "Demo Videos", + "index.videos.subtitle": "Watch the AI build real UE5 interfaces from scratch.", + "index.video1.title": "RTS UI Design", + "index.video1.desc": "Building a complete RTS game HUD with AI assistance", + "index.video2.title": "UE5 Editor Recreation", + "index.video2.desc": "Recreating the UE5 editor UI using only AI commands", + "index.video3.title": "UMG Editor Demo", + "index.video3.desc": "Live demonstration of UMG widget editing", + "index.video4.title": "Multi-Agent with Gemini", + "index.video4.desc": "Multi-agent AI architecture powered by Gemini", + + "index.cta.title": "Ready to Transform Your UE5 Workflow?", + "index.cta.subtitle": "Start from the open-source repository; use the Fab package only if you want marketplace installation.", + "index.cta.github": "Star on GitHub", + "index.cta.fab": "Optional Fab package →", + + "oss.badge": "MIT Open Source", + "oss.title": "Open Source Version", + "oss.subtitle": "Full-power UMG AI editing, community-driven, MIT licensed. Set up your own MCP server and start building.", + "oss.arch.label": "Architecture", + "oss.arch.title": "How It Works", + "oss.arch.subtitle": "The open source version uses MCP (Model Context Protocol) to bridge your AI client with UE5.", + "oss.apis.label": "40+ MCP Tools", + "oss.apis.title": "Complete API Reference", + "oss.apis.subtitle": "Every API is exposed as an MCP tool — call them from any MCP-compatible AI client.", + "oss.setup.label": "Quick Start", + "oss.setup.title": "Get Running in Minutes", + + "commercial.badge": "Fab Marketplace", + "commercial.title": "No Python. No Setup. Just Talk.", + "commercial.subtitle": "The commercial version eliminates all technical friction. Install via UE5 launcher, configure your API key, and start creating.", + "commercial.feat1.title": "Zero Python Dependency", + "commercial.feat1.desc": "Pure C++ implementation. No Python environment, no virtual env, no pip installs. Just install the plugin and go.", + "commercial.feat2.title": "Multi-Agent Architecture", + "commercial.feat2.desc": "Specialized AI agents work in parallel — Layout Agent, Blueprint Agent, Material Agent — coordinated by an Orchestrator for complex tasks.", + "commercial.feat3.title": "One-Click Installation", + "commercial.feat3.desc": "Install directly through the Epic Games Launcher / UE5 Marketplace. Auto-updates included. No GitHub cloning required.", + "commercial.feat4.title": "Priority Support", + "commercial.feat4.desc": "Dedicated support channel, faster bug fixes, early access to new features, and direct communication with the development team.", + "commercial.multiagent.label": "Architecture", + "commercial.multiagent.title": "Multi-Agent AI System", + "commercial.multiagent.subtitle": "Complex UI tasks are decomposed and handled by specialized agents working in parallel.", + "commercial.buy.title": "Get the Fab Package", + "commercial.buy.subtitle": "Available now on Fab Marketplace. One purchase, lifetime updates.", + "commercial.buy.cta": "Buy on Fab Marketplace →", + "commercial.faq.title": "Frequently Asked Questions", + + "features.badge": "Full Breakdown", + "features.title": "Features & Comparison", + "features.subtitle": "A complete view of every capability across both versions.", + "features.matrix.label": "API Matrix", + "features.matrix.title": "Capability Matrix", + + "arch.badge": "Technical Deep Dive", + "arch.title": "System Architecture", + "arch.subtitle": "Understand how UMG MCP connects your AI client to Unreal Engine's internals.", + "arch.oss.title": "Open Source Architecture", + "arch.commercial.title": "Commercial Multi-Agent Architecture", + + "workflow.badge": "How to Use", + "workflow.title": "Workflow & Process", + "workflow.subtitle": "From idea to pixel-perfect UMG — here's the full creative loop.", + + "roadmap.badge": "What's Coming", + "roadmap.title": "Development Roadmap", + "roadmap.subtitle": "The journey from experimental MCP plugin to full AI UI pipeline.", + "roadmap.phase1": "Phase 1 — Released", + "roadmap.phase1.title": "Core Foundation", + "roadmap.phase2": "Phase 2 — In Progress", + "roadmap.phase2.title": "Commercial & Multi-Agent", + "roadmap.phase3": "Phase 3 — Planned", + "roadmap.phase3.title": "Developer Experience", + "roadmap.phase4": "Phase 4 — Vision", + "roadmap.phase4.title": "Full AI UI Pipeline", + + "docs.badge": "Quick Start", + "docs.title": "Getting Started", + "docs.subtitle": "Choose your path: open source setup or instant commercial install.", + "docs.tab.oss": "Open Source", + "docs.tab.commercial": "Fab package", + + "contact.badge": "Get Help", + "contact.title": "Contact & Support", + "contact.subtitle": "We're here to help. Choose the right channel for your needs.", + "contact.github.title": "GitHub Issues", + "contact.github.desc": "Report bugs, request features, or ask technical questions for the open source version.", + "contact.fab.title": "Fab Marketplace Support", + "contact.fab.desc": "Purchase questions, license issues, or commercial version support.", + "contact.community.title": "Community Discussions", + "contact.community.desc": "Share your work, ask questions, and connect with other UMG MCP users." +} diff --git a/assets/i18n/zh.json b/assets/i18n/zh.json new file mode 100644 index 0000000..fd74614 --- /dev/null +++ b/assets/i18n/zh.json @@ -0,0 +1,172 @@ +{ + "nav.home": "首页", + "nav.features": "功能特性", + "nav.architecture": "技术架构", + "nav.workflow": "工作流程", + "nav.roadmap": "路线图", + "nav.docs": "快速开始", + "nav.commercial": "Fab 包", + "nav.cta": "可选 Fab 包 →", + + "footer.brand.desc": "首款专注于 UE5 UMG 的 MCP 插件,AI 驱动的 UI 创作,零技术门槛。", + "footer.product": "产品", + "footer.product.features": "功能特性", + "footer.product.commercial": "Fab 包", + "footer.product.roadmap": "路线图", + "footer.product.changelog": "更新日志", + "footer.resources": "资源", + "footer.resources.docs": "快速开始", + "footer.resources.architecture": "技术架构", + "footer.resources.workflow": "工作流程", + "footer.resources.github": "GitHub", + "footer.community": "社区", + "footer.community.issues": "提交问题", + "footer.community.fab": "Fab 商店", + "footer.community.discussions": "讨论区", + "footer.bottom.copy": "© 2025 UMG MCP。MIT 开源协议。", + "footer.bottom.oss": "开源版本", + "footer.bottom.fab": "Fab 包", + + "hero.badge": "开源 UMG MCP 项目", + "hero.headline1": "让 AI 直接", + "hero.headline2": "操作 UMG", + "hero.subtitle": "原生 UE5 UMG AI 编辑器——用自然语言描述你想要的界面,AI 即时构建。", + "hero.cta.github": "免费开始(GitHub)", + "hero.cta.fab": "可选 Fab 包 →", + "hero.stat.apis": "40+", + "hero.stat.apis.label": "MCP 工具接口", + "hero.stat.categories": "5", + "hero.stat.categories.label": "控件 / BP / 动画 / 材质 / HLSL", + "hero.stat.python": "0", + "hero.stat.python.label": "无需 Python(Fab 包)", + "hero.stat.agents": "多智能体", + "hero.stat.agents.label": "AI 架构(Fab 包)", + + "index.features.label": "核心能力", + "index.features.title": "真正理解 UMG 的 AI", + "index.features.subtitle": "从简单的按钮布局到复杂的蓝图逻辑——描述需求,AI 即时实现。", + "index.feat1.title": "对话式 UI 创作", + "index.feat1.desc": "用自然语言与 AI 交流。它理解你的意图,直接创建、修改或排列 UMG 控件,无需手动调整任何属性面板。", + "index.feat2.title": "蓝图逻辑生成", + "index.feat2.desc": "描述交互行为,AI 自动生成蓝图节点、设置变量绑定、创建动画触发器,并连接 UI 逻辑。", + "index.feat3.title": "材质与 HLSL 编辑", + "index.feat3.desc": "请求视觉效果、着色器或动态材质。AI 创建或修改 UE5 材质,甚至为自定义着色器节点编写 HLSL 代码。", + "index.feat4.title": "动画与序列器", + "index.feat4.desc": "让你的 UI 动起来。描述入场动画、循环待机或状态切换——AI 自动设置关键帧并配置 UMG 动画序列。", + + "index.compare.label": "两个版本", + "index.compare.title": "开源版 vs. Fab 包", + "index.compare.subtitle": "GitHub 仓库是 canonical 公开项目;Fab 是可选打包分发渠道。", + "index.compare.feature": "功能", + "index.compare.oss": "开源版(GitHub)", + "index.compare.fab": "Fab 包(Fab)", + "index.compare.core_api": "核心控件 API(40+ 工具)", + "index.compare.blueprint": "蓝图编辑", + "index.compare.anim": "动画/序列器 API", + "index.compare.material": "材质与 HLSL API", + "index.compare.python_server": "外部 Python MCP server", + "index.compare.chat_panel": "编辑器内 ChatWithUnreal 面板", + "index.compare.approval": "FabServer 审批队列", + "index.compare.providers": "Provider 设置 UI", + "index.compare.litert": "本地 LiteRT-LM 运行时", + "index.compare.python": "需要 Python", + "index.compare.install": "UE5 一键安装", + "index.compare.multiagent": "多智能体 AI", + "index.compare.support": "优先支持", + "index.compare.updates": "商业更新", + "index.compare.license": "授权协议", + "index.compare.license.oss": "MIT", + "index.compare.license.fab": "商业授权", + + "index.videos.label": "实际效果", + "index.videos.title": "演示视频", + "index.videos.subtitle": "观看 AI 从零构建真实 UE5 界面的全过程。", + "index.video1.title": "RTS UI 设计", + "index.video1.desc": "用 AI 协助构建完整的 RTS 游戏 HUD", + "index.video2.title": "UE5 编辑器重建", + "index.video2.desc": "仅用 AI 指令重建 UE5 编辑器界面", + "index.video3.title": "UMG 编辑器演示", + "index.video3.desc": "UMG 控件编辑实时演示", + "index.video4.title": "Gemini 多智能体协作", + "index.video4.desc": "由 Gemini 驱动的多智能体 AI 架构", + + "index.cta.title": "准备好革新你的 UE5 工作流了吗?", + "index.cta.subtitle": "从开源版本开始,或直接体验 Fab 上零配置的Fab 包。", + "index.cta.github": "在 GitHub 点 Star", + "index.cta.fab": "可选 Fab 包 →", + + "oss.badge": "MIT 开源", + "oss.title": "开源版本", + "oss.subtitle": "完整功能的 UMG AI 编辑,社区驱动,MIT 协议。搭建你自己的 MCP 服务器,立即开始构建。", + "oss.arch.label": "技术架构", + "oss.arch.title": "工作原理", + "oss.arch.subtitle": "开源版本使用 MCP(模型上下文协议)将你的 AI 客户端与 UE5 连接起来。", + "oss.apis.label": "40+ MCP 工具", + "oss.apis.title": "完整 API 参考", + "oss.apis.subtitle": "每个 API 都作为 MCP 工具暴露——可从任何兼容 MCP 的 AI 客户端调用。", + "oss.setup.label": "快速开始", + "oss.setup.title": "几分钟内运行起来", + + "commercial.badge": "Fab 商店", + "commercial.title": "无 Python。无配置。直接对话。", + "commercial.subtitle": "Fab 包消除一切技术障碍。通过 UE5 启动器安装,配置 API 密钥,立即开始创作。", + "commercial.feat1.title": "零 Python 依赖", + "commercial.feat1.desc": "纯 C++ 实现。无需 Python 环境、虚拟环境或 pip 安装。只需安装插件即可使用。", + "commercial.feat2.title": "多智能体架构", + "commercial.feat2.desc": "专业 AI 代理并行工作——布局代理、蓝图代理、材质代理——由编排器协调处理复杂任务。", + "commercial.feat3.title": "一键安装", + "commercial.feat3.desc": "直接通过 Epic Games 启动器安装。包含自动更新。无需克隆 GitHub 仓库。", + "commercial.feat4.title": "优先支持", + "commercial.feat4.desc": "专属支持渠道、更快的 Bug 修复、新功能抢先体验,以及与开发团队的直接沟通。", + "commercial.multiagent.label": "技术架构", + "commercial.multiagent.title": "多智能体 AI 系统", + "commercial.multiagent.subtitle": "复杂 UI 任务被分解并由专业代理并行处理。", + "commercial.buy.title": "获取Fab 包", + "commercial.buy.subtitle": "开源 UMG MCP 项目,一次购买,终身更新。", + "commercial.buy.cta": "在 Fab 商店购买 →", + "commercial.faq.title": "常见问题", + + "features.badge": "完整对比", + "features.title": "功能特性与对比", + "features.subtitle": "两个版本所有功能的完整视图。", + "features.matrix.label": "API 矩阵", + "features.matrix.title": "能力矩阵", + + "arch.badge": "技术深度解析", + "arch.title": "系统架构", + "arch.subtitle": "了解 UMG MCP 如何将你的 AI 客户端连接到 Unreal Engine 的内部。", + "arch.oss.title": "开源架构", + "arch.commercial.title": "Fab 包多智能体架构", + + "workflow.badge": "使用方法", + "workflow.title": "工作流程", + "workflow.subtitle": "从想法到像素级完美的 UMG——完整的创意循环。", + + "roadmap.badge": "即将推出", + "roadmap.title": "开发路线图", + "roadmap.subtitle": "从实验性 MCP 插件到完整 AI UI 管线的旅程。", + "roadmap.phase1": "第一阶段 — 已发布", + "roadmap.phase1.title": "核心基础", + "roadmap.phase2": "第二阶段 — 进行中", + "roadmap.phase2.title": "商业化与多智能体", + "roadmap.phase3": "第三阶段 — 计划中", + "roadmap.phase3.title": "开发者体验", + "roadmap.phase4": "第四阶段 — 愿景", + "roadmap.phase4.title": "完整 AI UI 管线", + + "docs.badge": "快速开始", + "docs.title": "入门指南", + "docs.subtitle": "选择你的路径:开源配置或Fab 包即时安装。", + "docs.tab.oss": "开源版", + "docs.tab.commercial": "Fab 包(Fab)", + + "contact.badge": "获取帮助", + "contact.title": "联系与支持", + "contact.subtitle": "我们随时为您提供帮助,请选择适合您需求的渠道。", + "contact.github.title": "GitHub Issues", + "contact.github.desc": "报告 Bug、提交功能请求,或针对开源版本提问。", + "contact.fab.title": "Fab 商店支持", + "contact.fab.desc": "购买问题、授权问题或Fab 包支持。", + "contact.community.title": "社区讨论", + "contact.community.desc": "分享你的作品、提问,并与其他 UMG MCP 用户交流。" +} diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..f980152 --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,466 @@ +/** + * UMG MCP — Main JavaScript + * Handles: i18n, navigation, animations, interactions + */ + +/* ── i18n ────────────────────────────────────────────── */ +const I18n = (() => { + let cache = {}; + let currentLang = 'zh'; + + function detectLang() { + const saved = localStorage.getItem('umgmcp_lang'); + if (saved) return saved; + const browser = (navigator.language || navigator.userLanguage || 'zh').toLowerCase(); + return browser.startsWith('zh') ? 'zh' : 'en'; + } + + async function load(lang) { + if (cache[lang]) return cache[lang]; + const base = getBase(); + try { + const res = await fetch(`${base}assets/i18n/${lang}.json`); + if (!res.ok) throw new Error('Failed to load i18n'); + cache[lang] = await res.json(); + return cache[lang]; + } catch (e) { + console.warn('i18n load error', e); + return {}; + } + } + + function apply(strings) { + document.querySelectorAll('[data-i18n]').forEach(el => { + const key = el.getAttribute('data-i18n'); + if (strings[key] !== undefined) { + if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') { + el.placeholder = strings[key]; + } else { + el.textContent = strings[key]; + } + } + }); + // data-i18n-html is intentionally omitted to prevent XSS via translation content. + // Use data-i18n (textContent) or data-i18n-title (attribute) only. + document.querySelectorAll('[data-i18n-title]').forEach(el => { + const key = el.getAttribute('data-i18n-title'); + if (strings[key] !== undefined) el.title = strings[key]; + }); + } + + async function setLang(lang, animate = true) { + currentLang = lang; + localStorage.setItem('umgmcp_lang', lang); + const strings = await load(lang); + if (animate) { + document.body.style.opacity = '0.85'; + document.body.style.transition = 'opacity 0.15s'; + } + apply(strings); + if (animate) { + setTimeout(() => { document.body.style.opacity = '1'; }, 150); + } + // update lang buttons + document.querySelectorAll('.lang-btn').forEach(btn => { + btn.classList.toggle('active', btn.dataset.lang === lang); + }); + document.documentElement.lang = lang === 'zh' ? 'zh-CN' : 'en'; + } + + function getCurrent() { return currentLang; } + function getString(key) { return cache[currentLang]?.[key] || key; } + + return { detectLang, setLang, getCurrent, getString }; +})(); + +/* ── Base path helper ──────────────────────────────────── */ +function getBase() { + const scripts = document.querySelectorAll('script[src]'); + for (const s of scripts) { + if (!s.src.includes('assets/js/main.js')) continue; + try { + // new URL() fully normalizes the path, decoding %2e%2e and resolving .. + const url = new URL(s.src); + if (url.origin !== location.origin) continue; + // pathname is already normalized; strip the known script suffix + const path = url.pathname; + const suffix = 'assets/js/main.js'; + if (!path.endsWith(suffix)) continue; + const base = path.slice(0, path.length - suffix.length); + // Normalize once more via URL API to be explicit, then validate + const normalized = new URL(base || '.', location.origin + '/').pathname; + if (/^[/a-zA-Z0-9_.-]*$/.test(normalized) && !normalized.includes('..')) { + return normalized; + } + } catch (_) { /* skip malformed src */ } + } + return './'; +} + +/* ── Navigation render ─────────────────────────────────── */ +function renderNav() { + const base = getBase(); + const pages = [ + { key: 'nav.home', href: `${base}index.html`, id: 'home' }, + { key: 'nav.features', href: `${base}features.html`, id: 'features' }, + { key: 'nav.architecture', href: `${base}architecture.html`, id: 'architecture' }, + { key: 'nav.workflow', href: `${base}workflow.html`, id: 'workflow' }, + { key: 'nav.roadmap', href: `${base}roadmap.html`, id: 'roadmap' }, + { key: 'nav.docs', href: `${base}getting-started.html`, id: 'docs' }, + { key: 'nav.commercial', href: `${base}commercial.html`, id: 'commercial' }, + ]; + + const currentPage = location.pathname.split('/').pop().replace('.html','') || 'index'; + + const linksHtml = pages.map(p => { + const active = (currentPage === p.id || (p.id === 'home' && (currentPage === '' || currentPage === 'index'))) ? ' class="active"' : ''; + return `${p.key}`; + }).join(''); + + const mobileLinksHtml = pages.map(p => + `${p.key}` + ).join(''); + + const navEl = document.getElementById('main-nav'); + if (!navEl) return; + navEl.innerHTML = ` + + + `; + + // Scroll behavior + window.addEventListener('scroll', () => { + navEl.classList.toggle('scrolled', window.scrollY > 20); + }, { passive: true }); + + // Mobile toggle + const toggle = document.getElementById('nav-toggle'); + const mobileMenu = document.getElementById('nav-mobile'); + toggle?.addEventListener('click', () => { + const open = mobileMenu.classList.toggle('open'); + toggle.setAttribute('aria-expanded', open); + toggle.querySelectorAll('span').forEach((s, i) => { + if (open) { + if (i === 0) s.style.cssText = 'transform:rotate(45deg) translate(5px,5px)'; + if (i === 1) s.style.cssText = 'opacity:0'; + if (i === 2) s.style.cssText = 'transform:rotate(-45deg) translate(5px,-5px)'; + } else { + s.style.cssText = ''; + } + }); + }); + // close on link click + mobileMenu?.querySelectorAll('a').forEach(a => { + a.addEventListener('click', () => { + mobileMenu.classList.remove('open'); + toggle.setAttribute('aria-expanded', 'false'); + toggle.querySelectorAll('span').forEach(s => { s.style.cssText = ''; }); + }); + }); + + // Lang buttons + document.querySelectorAll('.lang-btn').forEach(btn => { + btn.addEventListener('click', () => I18n.setLang(btn.dataset.lang)); + }); +} + +/* ── Footer render ─────────────────────────────────────── */ +function renderFooter() { + const base = getBase(); + const footerEl = document.getElementById('main-footer'); + if (!footerEl) return; + footerEl.innerHTML = ` +
+ + +
+ `; +} + +/* ── Scroll-reveal (IntersectionObserver) ──────────────── */ +function initReveal() { + const io = new IntersectionObserver((entries) => { + entries.forEach(e => { + if (e.isIntersecting) { + e.target.classList.add('visible'); + io.unobserve(e.target); + } + }); + }, { threshold: 0.12, rootMargin: '0px 0px -40px 0px' }); + + document.querySelectorAll('.reveal').forEach(el => io.observe(el)); +} + +/* ── Animated counters ─────────────────────────────────── */ +function initCounters() { + const io = new IntersectionObserver((entries) => { + entries.forEach(e => { + if (e.isIntersecting) { + animateCounter(e.target); + io.unobserve(e.target); + } + }); + }, { threshold: 0.5 }); + + document.querySelectorAll('[data-counter]').forEach(el => io.observe(el)); +} + +function animateCounter(el) { + const target = parseFloat(el.dataset.counter); + const suffix = el.dataset.suffix || ''; + const prefix = el.dataset.prefix || ''; + const duration = 1800; + const start = performance.now(); + function update(now) { + const t = Math.min((now - start) / duration, 1); + const ease = 1 - Math.pow(1 - t, 3); + const val = Math.round(ease * target); + el.textContent = prefix + val + suffix; + if (t < 1) requestAnimationFrame(update); + } + requestAnimationFrame(update); +} + +/* ── SVG flow animation ────────────────────────────────── */ +function initSvgFlows() { + const io = new IntersectionObserver((entries) => { + entries.forEach(e => { + if (e.isIntersecting) { + e.target.querySelectorAll('.svg-flow-line, .svg-flow-arrow').forEach(el => { + el.classList.add('animated'); + }); + io.unobserve(e.target); + } + }); + }, { threshold: 0.3 }); + + document.querySelectorAll('.diagram-wrap, .arch-diagram').forEach(el => io.observe(el)); +} + +/* ── Glow card mouse tracking ──────────────────────────── */ +function initGlowCards() { + document.querySelectorAll('.glow-card').forEach(card => { + card.addEventListener('mousemove', e => { + const rect = card.getBoundingClientRect(); + const x = ((e.clientX - rect.left) / rect.width) * 100; + const y = ((e.clientY - rect.top) / rect.height) * 100; + card.style.setProperty('--mx', x + '%'); + card.style.setProperty('--my', y + '%'); + }); + }); +} + +/* ── Hero typing animation ─────────────────────────────── */ +function initTyping() { + const el = document.getElementById('typing-target'); + if (!el) return; + + const lang = I18n.getCurrent(); + const phrases = lang === 'zh' + ? ['操作 UMG', '驱动 UI', '理解蓝图', '生成材质', '制作动画'] + : ['Speaks UMG', 'Builds UI', 'Edits Blueprints', 'Creates Materials', 'Drives Animations']; + + let phraseIdx = 0; + let charIdx = 0; + let deleting = false; + let paused = false; + + el.style.borderRight = '3px solid var(--accent)'; + el.style.animation = 'blinkCaret 0.8s step-end infinite'; + + function tick() { + const phrase = phrases[phraseIdx]; + if (paused) { + paused = false; + deleting = true; + setTimeout(tick, 1200); + return; + } + if (!deleting) { + el.textContent = phrase.slice(0, ++charIdx); + if (charIdx === phrase.length) { paused = true; setTimeout(tick, 80); return; } + setTimeout(tick, 80); + } else { + el.textContent = phrase.slice(0, --charIdx); + if (charIdx === 0) { + deleting = false; + phraseIdx = (phraseIdx + 1) % phrases.length; + setTimeout(tick, 400); + return; + } + setTimeout(tick, 40); + } + } + tick(); +} + +/* ── Hero particles ────────────────────────────────────── */ +function initParticles() { + const container = document.getElementById('hero-particles'); + if (!container) return; + const colors = ['#7c3aed','#2563eb','#06b6d4','#9d5cf6']; + const count = window.innerWidth < 768 ? 15 : 30; + for (let i = 0; i < count; i++) { + const p = document.createElement('div'); + p.className = 'particle'; + const size = 2 + Math.random() * 4; + p.style.cssText = ` + width:${size}px;height:${size}px; + background:${colors[Math.floor(Math.random()*colors.length)]}; + left:${Math.random()*100}%; + animation-duration:${8+Math.random()*12}s; + animation-delay:-${Math.random()*20}s; + `; + container.appendChild(p); + } +} + +/* ── FAQ accordion ─────────────────────────────────────── */ +function initFAQ() { + document.querySelectorAll('.faq-question').forEach(btn => { + btn.addEventListener('click', () => { + const answer = btn.nextElementSibling; + const isOpen = btn.classList.contains('open'); + // close all + document.querySelectorAll('.faq-question.open').forEach(b => { + b.classList.remove('open'); + b.nextElementSibling?.classList.remove('open'); + }); + if (!isOpen) { + btn.classList.add('open'); + answer?.classList.add('open'); + } + }); + }); +} + +/* ── Tabs ──────────────────────────────────────────────── */ +function initTabs() { + document.querySelectorAll('.tab-btn').forEach(btn => { + btn.addEventListener('click', () => { + const group = btn.closest('[data-tab-group]') || btn.closest('.tabs-wrap'); + const target = btn.dataset.tab; + group?.querySelectorAll('.tab-btn').forEach(b => b.classList.toggle('active', b === btn)); + group?.querySelectorAll('.tab-pane').forEach(p => p.classList.toggle('active', p.id === target)); + }); + }); +} + +/* ── Smooth anchor scroll ──────────────────────────────── */ +function initSmoothScroll() { + document.querySelectorAll('a[href^="#"]').forEach(a => { + a.addEventListener('click', e => { + const target = document.querySelector(a.getAttribute('href')); + if (target) { + e.preventDefault(); + const offset = 80; + window.scrollTo({ top: target.getBoundingClientRect().top + window.scrollY - offset, behavior: 'smooth' }); + } + }); + }); +} + +/* ── Main init ─────────────────────────────────────────── */ +document.addEventListener('DOMContentLoaded', async () => { + renderNav(); + renderFooter(); + + const lang = I18n.detectLang(); + await I18n.setLang(lang, false); + + initParticles(); + initTyping(); + initReveal(); + initCounters(); + initSvgFlows(); + initGlowCards(); + initFAQ(); + initTabs(); + initSmoothScroll(); +}); diff --git a/commercial.html b/commercial.html new file mode 100644 index 0000000..58bfa14 --- /dev/null +++ b/commercial.html @@ -0,0 +1,210 @@ + + + + + + Commercial Version — UMG MCP on Fab + + + + + + + +
+
+ +

No Python. No Setup.
Just Talk.

+

The commercial version eliminates all technical friction.

+ +
+
+ + +
+
+
+
+
🐍
+
+

Zero Python Dependency

+ New +
+

Pure C++ implementation. No Python environment, no virtual env, no pip installs.

+
+
+
🤖
+
+

Multi-Agent Architecture

+ Pro +
+

Specialized AI agents work in parallel — coordinated by an Orchestrator for complex tasks.

+
+
+
+

One-Click Installation

+

Install directly through the Epic Games Launcher. Auto-updates included.

+
+
+
🎯
+

Priority Support

+

Dedicated support channel, faster bug fixes, early access to new features.

+
+
+
+
+ + +
+
+
+ +

Multi-Agent AI System

+

Complex UI tasks are decomposed and handled by specialized agents working in parallel.

+
+
+ + + + User Conversation + Natural Language + + + + Orchestrator Agent + Task Planning & Coordination + + + + Layout Agent + Widget & Structure + + + Blueprint Agent + Logic & Events + + + Material Agent + Visual & HLSL + + + Anim Agent + Sequence & Keys + + + + + + + + + + + + + Parallel Execution + + + Commercial Version — Multi-Agent Architecture + +
+
+
+ + +
+
+
+

Why Upgrade to Commercial?

+

The commercial version is built for professionals who need results without setup friction.

+
+
+
+ +

Great for Experimentation

+

The open source version is fully functional and MIT licensed. Perfect for developers who want to customize, contribute, or understand how it works under the hood.

+
    +
  • Full source code access
  • +
  • 40+ MCP tools
  • +
  • MIT License — use in any project
  • +
  • Requires Python setup
  • +
  • Single agent only
  • +
+
+
+ +

Built for Production

+

Zero friction from install to creation. The commercial version removes every technical barrier so you can focus entirely on building great UE5 interfaces.

+
    +
  • Zero Python dependency
  • +
  • Multi-agent AI architecture
  • +
  • One-click UE5 launcher install
  • +
  • Priority support
  • +
  • Commercial updates
  • +
+
+
+
+
+ + +
+
+
+ +

Get the Commercial Version

+

Available now on Fab Marketplace. One purchase, lifetime updates.

+ +
+
+
+ + +
+
+
+

Frequently Asked Questions

+
+
+
+ +

The commercial version supports any LLM with an API key, including OpenAI GPT-4o, Anthropic Claude, and Google Gemini. You configure your own API key — no subscription beyond the plugin purchase.

+
+
+ +

UE5.3 and above are fully supported. UE5.1/5.2 may work but are not officially tested. We track Unreal's latest stable release and update accordingly.

+
+
+ +

Yes. The multi-agent orchestration layer — which decomposes tasks and runs specialized agents in parallel — is exclusive to the commercial version. The open source version uses a single-agent flow.

+
+
+ +

Yes. The commercial license covers use in commercial game projects and products. Please review the Fab Marketplace license terms for full details.

+
+
+ +

Yes. All updates for the purchased version are included. Major version upgrades may require a separate purchase depending on scope.

+
+
+ +

Refund policies are governed by Epic Games' Fab Marketplace terms. We recommend trying the open source version first to ensure compatibility with your workflow before purchasing.

+
+
+
+
+ +
+ + + diff --git a/contact.html b/contact.html new file mode 100644 index 0000000..77d0f44 --- /dev/null +++ b/contact.html @@ -0,0 +1,130 @@ + + + + + + Contact & Support — UMG MCP + + + + + + + +
+
+ +

Contact & Support

+

We're here to help. Choose the right channel for your needs.

+
+
+ +
+
+
+
+
+ +
+

GitHub Issues

+

Report bugs, request features, or ask technical questions for the open source version.

+ + Open an Issue → + + + View Repository + +
+ +
+
+ 🛒 +
+

Fab Marketplace Support

+

Purchase questions, license issues, or commercial version support.

+ + Visit Fab Listing → + + Commercial Version +
+ +
+
+ 💬 +
+

Community Discussions

+

Share your work, ask questions, and connect with other UMG MCP users.

+ + Join Discussions → + +
+
+
+
+ + +
+
+
+

Quick Links

+
+
+
+
📖
+

Getting Started Guide

+

Step-by-step setup for both open source and commercial versions.

+ Read Guide → +
+
+
🗺️
+

Roadmap

+

See what's released, in progress, and planned for UMG MCP.

+ View Roadmap → +
+
+
🔧
+

Architecture

+

Technical deep dive into how UMG MCP works under the hood.

+ Learn More → +
+
+
+
+ +
+ + + diff --git a/features.html b/features.html new file mode 100644 index 0000000..e2db4a4 --- /dev/null +++ b/features.html @@ -0,0 +1,178 @@ + + + + + + Features — UMG MCP + + + + + + +
+
+ +

Features & Comparison

+

A complete view of every capability across both versions.

+
+
+ + +
+
+
+
+
🎨
+

Widget Creation

+

Create any UMG widget type by description — Canvas, Text, Button, Image, ScrollBox, and more.

+
+
+
📐
+

Layout Control

+

Position, size, anchor, and align widgets with pixel precision using natural language.

+
+
+
🎭
+

Style & Theming

+

Set colors, fonts, padding, borders, and visual styles across your entire widget hierarchy.

+
+
+
+

Blueprint Logic

+

Wire up events, create variables, bind properties, and add interaction logic via Blueprint.

+
+
+
🎬
+

Animations

+

Create keyframe animations, set easing curves, and control playback via UMG animation tracks.

+
+
+
🌊
+

Materials & HLSL

+

Build dynamic materials, create shader effects, and write HLSL custom expressions.

+
+
+
+
+ + +
+
+
+

Complete Comparison

+

Every feature, side by side.

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureOpen Source (GitHub)Commercial (Fab)
Widget API
Create/Delete Widgets
Set Widget Properties
Layout & Anchoring
Widget Hierarchy
Style & Theming APIPartial
Blueprint API
Add/Get Variables
Widget-Variable Binding
Event Binding
Blueprint Compilation
Function GenerationBasic✓ Advanced
Animation API
Create Animations
Add Keyframes
Easing Curves
Complex SequencerBasic
Material API
Create Materials
Set Parameters
HLSL Custom Expressions
Material Instances
Platform & Setup
Python RequiredRequiredNot Required
UE5 Launcher Install
Auto Updates✗ Manual✓ Auto
Multi-Agent AI
Priority Support
LicenseMITCommercial
PriceFreeFab Marketplace
+
+
+
+ + +
+
+
+ +

Capability Matrix

+

Every MCP tool organized by category and supported widget type.

+
+
+
+
🧩
+

Container Widgets

+

CanvasPanel, HorizontalBox, VerticalBox, GridPanel, WrapBox, ScrollBox, Overlay, Border

+
+ Full Support +
+
+
+
📝
+

Text & Input

+

TextBlock, RichTextBlock, EditableText, EditableTextBox, MultiLineEditableText, SpinBox

+
+ Full Support +
+
+
+
🖱️
+

Interactive Widgets

+

Button, CheckBox, ComboBox, Slider, ProgressBar, Image, Throbber, CircularThrobber

+
+ Full Support +
+
+
+
🎨
+

Visual & Media

+

Image, BackgroundBlur, InvalidationBox, RetainerBox, NamedSlot, UserWidget

+
+ Partial +
+
+
+
+
+ + +
+
+
+

Start Building Today

+

Whether you choose open source or commercial, your AI-powered UMG workflow starts now.

+ +
+
+
+ +
+ + + diff --git a/getting-started.html b/getting-started.html new file mode 100644 index 0000000..7f86705 --- /dev/null +++ b/getting-started.html @@ -0,0 +1,321 @@ + + + + + + Getting Started — UMG MCP + + + + + + + +
+
+ +

Getting Started

+

Choose your path: open source setup or instant commercial install.

+
+
+ +
+
+ +
+ + +
+ +
+ +
+ +
+ Prerequisites +

UE5.3+, Python 3.9+, an MCP-compatible AI client (Claude Desktop, Cursor, or custom)

+
+ +
+
+
🎮
+
+
Unreal Engine
+

5.3 or newer

+
+
+
+
🐍
+
+
Python
+

3.9 or newer

+
+
+
+
🤖
+
+
AI Client
+

MCP compatible

+
+
+
+
🔑
+
+
API Key
+

Gemini / GPT / Claude

+
+
+
+ +
+
+
1
+
+

Clone the repository

+
+ bash +
git clone https://github.com/winyunq/UnrealMotionGraphicsMCP.git
+cd UnrealMotionGraphicsMCP
+
+
+
+
+
2
+
+

Copy plugin to your UE5 project

+

Copy the Source/ folder into your UE5 project's Plugins/UmgMcp/ directory.

+
+ bash +
# Windows (PowerShell)
+Copy-Item -Recurse Source\ "C:\MyProject\Plugins\UmgMcp\"
+
+# macOS / Linux
+cp -r Source/ /path/to/MyProject/Plugins/UmgMcp/
+
+
+
+
+
3
+
+

Enable the plugin in UE5

+

Open your project → Edit → Plugins → search "UMG MCP" → Enable → Restart UE5.

+
+

If prompted to rebuild modules, click Yes. This compiles the C++ plugin for your platform.

+
+
+
+
+
4
+
+

Install Python dependencies

+
+ bash +
cd UnrealMotionGraphicsMCP
+pip install -r requirements.txt
+
+
+
+
+
5
+
+

Configure UmgMcpConfig.json

+

The config file at the repo root controls the server port and settings.

+
+ json +
{
+  "host": "localhost",
+  "port": 19202,     // must match UE5 plugin setting
+  "log_level": "info"
+}
+
+
+
+
+
6
+
+

Start the MCP server

+
+ bash +
python Scripts/mcp_server.py
+# Server listening on localhost:19202
+
+
+
+
+
7
+
+

Connect your AI client

+

Add the UMG MCP server to your MCP client configuration. Example for Claude Desktop (claude_desktop_config.json):

+
+ json +
{
+  "mcpServers": {
+    "umg-mcp": {
+      "command": "python",
+      "args": ["/path/to/Scripts/mcp_server.py"]
+    }
+  }
+}
+
+
+
+
+
8
+
+

Start building!

+

Open a UMG widget in UE5, then chat with your AI. Try:

+
+ "Create a button in the center of the canvas. Label it 'Start Game', size 200x60px, purple background, white text, size 24." +
+
+
+
+
+ + +
+ +
+ Prerequisites +

UE5.3+, Epic Games Launcher, API key from Gemini / OpenAI / Anthropic. No Python required.

+
+ +
+
+
🎮
+
+
Unreal Engine
+

5.3 or newer

+
+
+
+
🏪
+
+
Epic Launcher
+

Fab Marketplace

+
+
+
+
🔑
+
+
API Key
+

Gemini / GPT / Claude

+
+
+
+ +
+
+
1
+
+

Purchase on Fab Marketplace

+

Visit the UMG MCP listing on Fab and complete the purchase.

+ +
+
+
+
2
+
+

Install from Epic Launcher

+

Open the Epic Games Launcher → Library → Vault. Find UMG MCP and click "Install to Engine".

+
+

Select the correct UE5 engine version. The plugin installs automatically — no file copying needed.

+
+
+
+
+
3
+
+

Enable the plugin in your project

+

Open your project → Edit → Plugins → search "UMG MCP" → Enable → Restart.

+
+
+
+
4
+
+

Configure your API key

+

In UE5, open Edit → Project Settings → UMG MCP. Enter your LLM API key and select your preferred AI model.

+
+

The commercial version supports Gemini, OpenAI GPT, and Anthropic Claude. Your API key is stored securely in project settings and never transmitted anywhere except directly to the LLM API.

+
+
+
+
+
5
+
+

Open the UMG MCP Chat Panel

+

Go to Window → UMG MCP to open the built-in chat panel inside UE5. No external applications needed.

+
+
+
+
6
+
+

Start building!

+

Open a UMG widget blueprint, click into the chat panel, and describe what you want to build. The multi-agent system handles the rest.

+
+ "Build a complete main menu with a title, Play/Settings/Quit buttons, animated background, and smooth slide-in animations." +
+

The orchestrator will split this into Layout, Animation, and Style sub-tasks and execute them in parallel.

+
+
+
+
+
+
+
+ + +
+
+
+

Common Issues

+
+
+
+ +

Check that the port in UmgMcpConfig.json matches the port in the UE5 plugin settings. Default is 19202. Ensure no firewall is blocking localhost connections. Also verify the Python server is running before launching UE5.

+
+
+ +

This is normal on first install. Click Yes to allow UE5 to compile the C++ plugin for your platform. This may take 2-5 minutes. Ensure you have Visual Studio (Windows) or Xcode (Mac) installed.

+
+
+ +

Make sure the MCP server has been updated to the latest version matching your plugin. Run git pull and restart the server. Also verify your MCP client has loaded the server correctly.

+
+
+ +

Ensure the UMG widget is open in the UE5 Widget Blueprint Editor. The plugin operates on the currently active widget. If the widget is not open, operations will fail silently.

+
+
+
+
+ +
+ + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..4094c50 --- /dev/null +++ b/index.html @@ -0,0 +1,218 @@ + + + + + + UMG MCP — AI-Powered UE5 UMG Editor + + + + + + + + + + +
+
+
+
+
+
+
+
+ + Open-source UMG MCP for Unreal Engine +
+

+ The AI That
+ +

+

+ Native UE5 UMG AI editor — just describe what you want, watch it build your interface in real time. +

+ + + +
+
+ 40+ + MCP Tools +
+
+ 5 + Widget / BP / Anim / Material / HLSL +
+
+ 0 + Python bridge documented +
+
+ AI + Multi-Agent Architecture +
+
+
+
+ + +
+
+
+ +

AI That Understands UMG

+

From simple button placement to complex blueprint logic — describe it, and the AI builds it.

+
+
+
+
🎨
+

Conversational UI Creation

+

Talk to your AI in natural language. It reads your intent and directly creates, modifies, or arranges UMG widgets without you touching a single property panel.

+
+ Widget API + 40+ Tools +
+
+
+
+

Blueprint Logic Generation

+

Describe interactions and behaviors. The AI generates Blueprint nodes, sets variable bindings, creates animation triggers, and wires up your UI logic.

+
+ Blueprint API +
+
+
+
🌊
+

Material & HLSL Editing

+

Ask for visual effects, shaders, or dynamic materials. The AI creates or modifies UE5 materials and even writes HLSL code for custom shader nodes.

+
+ Material API + HLSL +
+
+
+
🎬
+

Animation & Sequencer

+

Bring your UI to life. Describe entrance animations, idle loops, or state transitions — the AI sets keyframes and configures UMG animation sequences.

+
+ Animation API +
+
+
+
+
+ + +
+
+
+ +

Open Source and Fab Package

+

The GitHub repository is the canonical public project; Fab is an optional packaged distribution.

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
FeatureOpen Source (GitHub)Fab package
Core Widget API (40+ tools)
Blueprint Editing
Animation/Sequencer API
Material & HLSL API
External Python MCP server
In-editor ChatWithUnreal panel
FabServer approval queue
Provider settings UI
Local LiteRT-LM runtime
Requires Python
One-click UE5 install
Multi-Agent AI
Priority Support
LicenseMITCommercial
+
+ +
+
+ + +
+
+
+ +

Demo Videos

+

Watch the AI build real UE5 interfaces from scratch.

+
+
+
+ +
+

RTS UI Design

+

Building a complete RTS game HUD with AI assistance

+
+
+
+ +
+

UE5 Editor Recreation

+

Recreating the UE5 editor UI using only AI commands

+
+
+
+ +
+

UMG Editor Demo

+

Live demonstration of UMG widget editing

+
+
+
+ +
+

Multi-Agent with Gemini

+

Multi-agent AI architecture powered by Gemini

+
+
+
+
+
+ + +
+
+
+

Ready to Transform Your UE5 Workflow?

+

Start from the open-source repository; use the Fab package only if you want marketplace installation.

+ +
+
+
+ +
+ + + diff --git a/index_zh.html b/index_zh.html new file mode 100644 index 0000000..a6b0baa --- /dev/null +++ b/index_zh.html @@ -0,0 +1,14 @@ + + + + + + + UMG MCP | 中文入口 + + + + +

进入 UMG MCP 中文页面

+ + diff --git a/open-source.html b/open-source.html new file mode 100644 index 0000000..d33652f --- /dev/null +++ b/open-source.html @@ -0,0 +1,250 @@ + + + + + + Open Source — UMG MCP + + + + + + + +
+
+ +

Open Source Version

+

Full-power UMG AI editing, community-driven, MIT licensed.

+ +
+
+ + +
+
+
+ +

How It Works

+

The open source version uses MCP (Model Context Protocol) to bridge your AI client with UE5.

+
+
+ + + + AI Client + Gemini / GPT / Claude + + + + MCP Server + Python Process + + + + UmgMcpBridge + C++ UE5 Plugin · TCP Socket + + + + UMG Widget + Layout & Style + + + Blueprint + Logic & Events + + + Material + HLSL Shader + + + Animation + Sequencer + + + + + MCP + + + + + TCP/JSON + + + + + + + + + Open Source Architecture — MCP Protocol + +
+
+
+ + +
+
+
+ +

Complete API Reference

+

Every API is exposed as an MCP tool — call them from any MCP-compatible AI client.

+
+ +
+
+ Widget API +

Widget Creation & Layout

+
+
+
create_widget
+
delete_widget
+
get_widget_info
+
set_widget_property
+
list_widgets
+
move_widget
+
resize_widget
+
set_slot_property
+
add_widget_to_canvas
+
create_widget_hierarchy
+
set_widget_visibility
+
clone_widget
+
+
+ +
+
+ Blueprint API +

Blueprint & Logic

+
+
+
add_blueprint_variable
+
set_blueprint_variable
+
get_blueprint_variables
+
bind_widget_to_variable
+
add_event_binding
+
compile_blueprint
+
get_blueprint_functions
+
add_blueprint_function
+
+
+ +
+
+ Animation API +

Animation & Sequencer

+
+
+
create_animation
+
add_animation_track
+
add_keyframe
+
set_animation_length
+
play_animation
+
list_animations
+
delete_animation
+
set_loop_animation
+
+
+ +
+
+ Material API +

Materials & HLSL

+
+
+
create_material
+
set_material_parameter
+
add_material_node
+
set_hlsl_expression
+
apply_material_to_widget
+
get_material_info
+
create_material_instance
+
compile_material
+
+
+ +
+
+ Editor API +

Editor Utilities

+
+
+
save_asset
+
open_asset
+
get_project_info
+
list_assets
+
create_folder
+
import_texture
+
set_editor_focus
+
undo_action
+
+
+
+
+ + +
+
+
+ +

Get Running in Minutes

+
+
+
+
1
+
+

Install the Plugin

+

Clone the repository and copy the plugin to your UE5 project's Plugins/ folder.

+
+ bash +
git clone https://github.com/winyunq/UnrealMotionGraphicsMCP.git
+cp -r UnrealMotionGraphicsMCP/Source MyProject/Plugins/UmgMcp
+
+
+
+
+
2
+
+

Enable the Plugin in UE5

+

Open your project in UE5, go to Edit → Plugins, search for "UMG MCP", and enable it. Restart the editor.

+
+
+
+
3
+
+

Start the MCP Server

+

Run the Python MCP server included in the Scripts/ directory.

+
+ bash +
pip install -r requirements.txt
+python Scripts/mcp_server.py
+
+
+
+
+
4
+
+

Connect Your AI Client

+

Point your MCP-compatible AI client (Claude Desktop, Cursor, etc.) to the server endpoint and start describing your UI.

+
+
+
+ +
+
+ +
+ + + diff --git a/roadmap.html b/roadmap.html new file mode 100644 index 0000000..dcc3ceb --- /dev/null +++ b/roadmap.html @@ -0,0 +1,197 @@ + + + + + + Roadmap — UMG MCP + + + + + + + +
+
+ +

Development Roadmap

+

The journey from experimental MCP plugin to full AI UI pipeline.

+
+
+ + +
+
+
+
+
+ Released +
+
+
+ In Progress +
+
+
+ Planned +
+
+
+ Vision +
+
+
+
+ + +
+
+
+ + +
+
+
+
Phase 1 — Released
+

Core Foundation

+
    +
  • 40+ MCP tool APIs for UMG
  • +
  • Widget creation, deletion, property editing
  • +
  • Layout control (position, size, anchoring)
  • +
  • Blueprint variable & event binding
  • +
  • Blueprint compilation
  • +
  • Animation/Sequencer API
  • +
  • Material creation & editing
  • +
  • HLSL custom expression support
  • +
  • TCP socket bridge (C++ ↔ Python)
  • +
  • Open source on GitHub (MIT)
  • +
  • Compatible with Gemini, GPT, Claude
  • +
+
+ ✓ Live Now + GitHub → +
+
+
+ + +
+
+
+
Phase 2 — In Progress
+

Commercial & Multi-Agent

+
    +
  • Commercial version on Fab Marketplace
  • +
  • Zero Python dependency (pure C++)
  • +
  • Multi-agent orchestration system
  • +
  • Specialized agents (Layout, Blueprint, Material, Anim)
  • +
  • Style & Theming API
  • +
  • API key configuration UI
  • +
  • Improved error recovery
  • +
  • UE5 Launcher distribution
  • +
+
+ 🔄 In Progress + Fab → +
+
+
+ + +
+
+
+
Phase 3 — Planned
+

Developer Experience

+
    +
  • Visual drag-and-drop widget preview
  • +
  • Real-time preview pane in AI chat
  • +
  • Widget template library
  • +
  • Design system / style tokens
  • +
  • More AI platform integrations
  • +
  • Batch operations API
  • +
  • Undo history integration
  • +
  • Plugin settings & preferences UI
  • +
+
+ 📅 Planned +
+
+
+ + +
+
+
+
Phase 4 — Vision
+

Full AI UI Pipeline

+
    +
  • Full UI generation from image/mockup input
  • +
  • Design-to-UMG conversion pipeline
  • +
  • AI-powered responsive layout engine
  • +
  • Cross-project widget sharing
  • +
  • Team collaboration features
  • +
  • UMG-to-design export
  • +
  • AI accessibility checker
  • +
  • Performance profiling integration
  • +
+
+ 🔭 Vision +
+
+
+ +
+
+
+ + +
+
+
+

Shape the Roadmap

+

Have a feature request? The open source community drives the roadmap. Open an issue or start a discussion on GitHub.

+ +
+
+
+ +
+ + + diff --git a/workflow.html b/workflow.html new file mode 100644 index 0000000..3dfb2ea --- /dev/null +++ b/workflow.html @@ -0,0 +1,216 @@ + + + + + + Workflow — UMG MCP + + + + + + + +
+
+ +

Workflow & Process

+

From idea to pixel-perfect UMG — here's the full creative loop.

+
+
+ + +
+
+
+

The AI-UMG Creation Loop

+

Every iteration makes your UI better — no context switching required.

+
+
+ + + + + + + + + + + ① Describe + Natural language + UI intent + + + + + + ② AI Analyzes + LLM plans + tool sequence + + + + + + ③ MCP Calls + UMG tools + execute + + + + + + ④ UMG Updates + Live editor + changes + + + + + + ⑤ Review + You see result + immediately + + + + + + Iterate + + + + + + Iterate until perfect + +
+
+
+ + +
+
+
+

Real Use Cases

+

See exactly what you'd say to the AI, and what it does.

+
+
+
+ Game HUD +

RTS Game Interface

+
"Create a minimap widget in the bottom-right corner, 200x200px. Add a health bar and resource counters at the top. Use a dark semi-transparent background."
+

The AI creates a CanvasPanel, adds an Image for the minimap, a ProgressBar for health, TextBlocks for resources, and styles them with the specified colors and transparency.

+
+
+ Inventory UI +

RPG Inventory Screen

+
"Build a 6x4 grid inventory. Each slot should be a 64x64 button with a darker background on hover. Add a tooltip panel that appears on the right side."
+

Creates a UniformGridPanel with 24 Button children, configures hover styles, adds a tooltip overlay with animation states, and wires the hover events in Blueprint.

+
+
+ Material FX +

Animated Shader Effect

+
"Add a glowing pulsing border effect to the selected inventory slot. Use a sine wave animation on the emissive intensity, cycling every 1.5 seconds."
+

Creates a material with a Time node feeding a Sine expression, connects to Emissive Color, applies to the slot's brush material, and creates the UMG animation sequence.

+
+
+ Main Menu +

Cinematic Main Menu

+
"Build a main menu with Play, Settings, Quit buttons. Animate them sliding in from the left with 0.1s stagger. Add a blurred background overlay."
+

Creates a VerticalBox with styled buttons, configures BackgroundBlur, and creates three staggered UMG animations with translate-X keyframes and ease-out curves.

+
+
+ Data Binding +

Dynamic Stats Dashboard

+
"Create a player stats panel. Bind the health text to a PlayerHealth float variable, and the XP bar to a PlayerXP variable. Compile the blueprint."
+

Adds Blueprint variables, binds TextBlock text to PlayerHealth via a Format Text node, binds ProgressBar percent to PlayerXP, and triggers compilation — all in one step.

+
+
+ Iteration +

Rapid Iteration

+
"The health bar looks too thin. Make it 40px tall and round the corners. Also change the fill color to a gradient from green to red based on remaining HP."
+

Modifies the existing ProgressBar dimensions, applies corner rounding via slot properties, creates a new dynamic material with a Lerp on the fill color, and re-applies it.

+
+
+
+
+ + +
+
+
+

Tips for Best Results

+

Get more from your AI UMG sessions.

+
+
+
+

🎯 Be Specific About Sizes & Positions

+

Instead of "make it bigger", say "set width to 320px, height to 48px". Exact values produce better results than relative descriptions.

+
+
+

🧩 Build Hierarchically

+

Start with the outer container, then add children. The AI handles hierarchy best when you describe the structure top-down.

+
+
+

🔄 Iterate Incrementally

+

Make small changes per message. "Change the button color to #ff6b35" is more reliable than trying to do everything at once.

+
+
+

📸 Reference UE5 Widget Names

+

Using exact UE5 widget names (CanvasPanel, HorizontalBox, ProgressBar) helps the AI pick the right tool. The AI knows them all.

+
+
+
+
+ +
+ + +