如果你已经在用 Claude Code、Cursor、Codex 这一类 AI 客户端写代码,但每次切回 Unity 编辑器调场景、改组件、点 Play 都还是手动操作,那中间这一段其实可以让 AI 替你做掉。
funplay-unity-mcp 是一个开源的 Unity Editor 插件(MIT 许可),运行起来后会在 Unity 进程内监听一个本地 HTTP 端口,把场景、Prefab、Asset、PlayMode 状态以 MCP 协议暴露给外部 AI 客户端。客户端可以列出工具、调用工具、读资源------也就是说,"在场景里创建 5 个浮空平台并随机摆放"、"把所有 Enemy_ 开头的对象改成 trigger"、"进入 PlayMode 截一张图给我"这一类操作,可以直接用自然语言交给 AI。
这篇文章面向第一次接触它的人,记录从零到第一次让 AI 真正动 Unity 的完整流程。
一、它解决什么问题
绝大多数 AI 编程客户端只能读写文件、跑命令行。Unity 项目的状态------当前打开的场景、选中的 GameObject、Inspector 里的组件值、PlayMode 是否运行------它们读不到,更动不了。要么 AI 写一段编辑器脚本让你去 Unity 里手动执行,要么你来回截图描述。
funplay-unity-mcp 把这层桥搭起来。装上之后,AI 客户端不再只看到你的 .cs 和 .unity 文本,它能看到运行中的 Unity 编辑器本身。
整体调用链是这样的:
#mermaid-svg-RfrEV1suRTeir3sD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RfrEV1suRTeir3sD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RfrEV1suRTeir3sD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RfrEV1suRTeir3sD .error-icon{fill:#552222;}#mermaid-svg-RfrEV1suRTeir3sD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RfrEV1suRTeir3sD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RfrEV1suRTeir3sD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RfrEV1suRTeir3sD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RfrEV1suRTeir3sD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RfrEV1suRTeir3sD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RfrEV1suRTeir3sD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RfrEV1suRTeir3sD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RfrEV1suRTeir3sD .marker.cross{stroke:#333333;}#mermaid-svg-RfrEV1suRTeir3sD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RfrEV1suRTeir3sD p{margin:0;}#mermaid-svg-RfrEV1suRTeir3sD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-RfrEV1suRTeir3sD .cluster-label text{fill:#333;}#mermaid-svg-RfrEV1suRTeir3sD .cluster-label span{color:#333;}#mermaid-svg-RfrEV1suRTeir3sD .cluster-label span p{background-color:transparent;}#mermaid-svg-RfrEV1suRTeir3sD .label text,#mermaid-svg-RfrEV1suRTeir3sD span{fill:#333;color:#333;}#mermaid-svg-RfrEV1suRTeir3sD .node rect,#mermaid-svg-RfrEV1suRTeir3sD .node circle,#mermaid-svg-RfrEV1suRTeir3sD .node ellipse,#mermaid-svg-RfrEV1suRTeir3sD .node polygon,#mermaid-svg-RfrEV1suRTeir3sD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RfrEV1suRTeir3sD .rough-node .label text,#mermaid-svg-RfrEV1suRTeir3sD .node .label text,#mermaid-svg-RfrEV1suRTeir3sD .image-shape .label,#mermaid-svg-RfrEV1suRTeir3sD .icon-shape .label{text-anchor:middle;}#mermaid-svg-RfrEV1suRTeir3sD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RfrEV1suRTeir3sD .rough-node .label,#mermaid-svg-RfrEV1suRTeir3sD .node .label,#mermaid-svg-RfrEV1suRTeir3sD .image-shape .label,#mermaid-svg-RfrEV1suRTeir3sD .icon-shape .label{text-align:center;}#mermaid-svg-RfrEV1suRTeir3sD .node.clickable{cursor:pointer;}#mermaid-svg-RfrEV1suRTeir3sD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RfrEV1suRTeir3sD .arrowheadPath{fill:#333333;}#mermaid-svg-RfrEV1suRTeir3sD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RfrEV1suRTeir3sD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RfrEV1suRTeir3sD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RfrEV1suRTeir3sD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RfrEV1suRTeir3sD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RfrEV1suRTeir3sD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RfrEV1suRTeir3sD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RfrEV1suRTeir3sD .cluster text{fill:#333;}#mermaid-svg-RfrEV1suRTeir3sD .cluster span{color:#333;}#mermaid-svg-RfrEV1suRTeir3sD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RfrEV1suRTeir3sD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RfrEV1suRTeir3sD rect.text{fill:none;stroke-width:0;}#mermaid-svg-RfrEV1suRTeir3sD .icon-shape,#mermaid-svg-RfrEV1suRTeir3sD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RfrEV1suRTeir3sD .icon-shape p,#mermaid-svg-RfrEV1suRTeir3sD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RfrEV1suRTeir3sD .icon-shape .label rect,#mermaid-svg-RfrEV1suRTeir3sD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RfrEV1suRTeir3sD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RfrEV1suRTeir3sD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RfrEV1suRTeir3sD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} HTTP / JSON-RPC
AI 客户端
Claude Code / Cursor / Codex
Funplay MCP Server
(Unity 进程内)
Unity Editor 主线程
Scene / Prefab / Asset / PlayMode
server 跑在 Unity 进程内部,意味着它直接拥有完整的 Unity Editor API------SceneView、PrefabStage、AssetDatabase、PlayMode 状态都是同进程访问,没有跨进程 IPC,也不需要额外的守护进程。
二、环境要求
- Unity 2022.3 或更高版本(已在 6000.x 上验证)
- macOS / Windows / Linux 编辑器都可以
- 任意一款支持 MCP 的 AI 客户端:Claude Code、Cursor、VS Code、Codex、Trae、Kiro、Windsurf 等
- 网络上仅监听 127.0.0.1:8765,不会暴露到外网
整个包是 Editor-only 的(asmdef 里 includePlatforms 限定为 Editor),构建出去的游戏不会带进任何运行时代码。
三、安装
推荐用 UPM Git URL 安装,最简单。
打开 Unity 编辑器,菜单 Window → Package Manager → 左上角 + → Add package from git URL,填入:
https://github.com/FunplayAI/funplay-unity-mcp.git
回车,等 Package Manager 拉完。完成后菜单栏会多出一个 Funplay 顶级菜单。
如果不想走 Git,可以去仓库 Releases 页下载对应版本的 .unitypackage 文件离线导入,效果一致。
四、启动 MCP Server
菜单点开 Funplay → MCP Server,会出来一个面板。点 Start。
服务起来后,下方 Recent Activity 区域会开始记录最近发生的工具调用。这个面板就是你和 AI 之间发生过什么事的"控制台"。
默认端口 8765,如果被占用可以在面板里改。改完之后插件会自动按新端口重启 transport,不需要你操心。
校验一下服务是真的起来了,开一个终端:
curl -X POST http://127.0.0.1:8765/ \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
应该看到一个很长的 JSON,里面包含一堆工具定义。这就是 MCP 客户端马上要看到的工具清单。
五、把 AI 客户端接上
Funplay MCP Server 面板里有一个"一键 MCP 配置"按钮,选你用的客户端,插件会自动把配置写进对应文件。这是最省事的路径。
如果想手动写,下面是几种主流客户端的最小可行配置。
Claude Code
配置位置:用户级 ~/.claude.json 或项目级 .mcp.json。
{
"mcpServers": {
"funplay": {
"type": "http",
"url": "http://127.0.0.1:8765/"
}
}
}
写完重启 Claude Code,新对话里输入 /mcp,能看到 funplay 在列表里就成了。
Cursor
打开 Cursor Settings → MCP,添加一项:
{
"mcpServers": {
"funplay": {
"url": "http://127.0.0.1:8765/"
}
}
}
Codex (CLI)
Codex CLI 配置在 ~/.config/codex/config.toml:
[mcp_servers.funplay]
url = "http://127.0.0.1:8765/"
接好之后,客户端这边在新对话里就能直接看到 Funplay 提供的工具。
六、第一次让 AI 真正动场景
这一步是分水岭:之前所有配置都是为了让 AI "看见" Unity,现在让它"动手"。
打开任意 Unity 项目,新建或打开一个空场景。然后在 AI 客户端里输入:
在当前场景里以 (0,0,0) 为中心、半径 3 的圆周上等距创建 6 个 Cube,命名为 Ring_0 到 Ring_5,每个染上不同的颜色。
AI 客户端会调用 funplay 暴露的工具------多半是 execute_code------把这段意图翻译成一段 C# 编辑器代码,立即在你的 Unity 编辑器里执行。整个过程你不需要切回 Unity,但切回去之后 Hierarchy 里就会真的躺着 6 个 Cube。
而且因为插件用 Undo API 注册了所有改动,按一下 Ctrl+Z 这 6 个 Cube 一次性消失,完全符合 Unity 的撤销直觉。
如果你要的是更精细的工作流,例子比如:
- "把当前选中的 GameObject 的 Rigidbody.mass 改成 2.5"
- "把 Assets/Prefabs/Enemy.prefab 打开,给它加一个 BoxCollider 设成 trigger,保存"
- "把当前场景里所有 Light 的强度乘以 0.5"
- "进入 PlayMode 跑 3 秒,截一张 Game 视图的图给我"
这些都不需要你手动写一行编辑器脚本,AI 客户端会按需要调用合适的工具组合完成。
七、execute_code:核心是这一个工具
如果你看过工具清单,会发现里面有 80 多个工具。但其中最值钱的就一个:execute_code。
execute_code 接受一段 C# 片段,在 Unity 进程内通过 CodeDom + 反射就地编译执行------不写 .cs 文件,不触发 domain reload。这意味着 AI 可以为你当前这一个任务"临时写一个编辑器工具",跑完即弃。
举个例子,"把场景里所有 tag 为 Enemy 的对象按 X 坐标排序后重新命名为 Enemy_01..." 这种需求,传统做法是写一段 EditorWindow 脚本放进 Assets/Editor/,跑完再删;用 execute_code,AI 直接把这段逻辑作为参数发过来,跑完场景里就是排好序的状态,没有任何脚本残留。
实际开发里你会发现,很多看似需要"加一个工具"的需求,其实 execute_code 已经覆盖了。这也是为什么这个插件即便只暴露 core profile 的 29 个工具,AI 也几乎不缺工具用。
八、Play Mode 闭环
游戏开发跟普通后端开发最大的区别是:很多事情只有进入 Play Mode 才能验证。funplay 把这个闭环也连上了。
AI 可以:
- 调用 enter_play_mode / exit_play_mode 控制运行状态
- 模拟键盘鼠标输入(基于 InputSystem)
- 截 Game / Scene 视图的图,直接以图片形式返回给客户端
- 读取 Console 错误、Profiler 性能数据
这意味着 AI 不仅能改场景,还能"自己跑一遍验证"。比如调一个跳跃手感,AI 可以改 Rigidbody 参数 → 进入 PlayMode → 模拟按空格 → 截图返回 → 根据观察的轨迹再调参数。这就是闭环。
一个注意点:在 Play Mode 运行期间不要请求重编(request_recompile),Unity 会丢弃这个请求。插件本身在这种情况下会返回一个明确的错误,所以 AI 通常会先退出 Play Mode 再做需要重编的事。
九、随手装一个工作流 skill
如果你用 Claude Code,菜单里还有一项 Funplay → Project Skills。点开把 unity-mcp-workflow 装到当前项目,Claude Code 之后会自动按这套工作流来用 Funplay 工具------比如优先用结构化的工具读编辑器状态而不是瞎写代码、改完之后回读校验、合理使用 instanceId 等等。这是把"怎么有效地用这套工具"的经验沉淀进去了,第一次用强烈推荐装上。
十、下一步
到这一步你已经完成了:插件装上、服务跑起来、AI 客户端连上、第一次让 AI 改了场景、知道 execute_code 是核心、Play Mode 闭环可用。
如果想看插件本身或提 issue:
- 仓库:https://github.com/FunplayAI/funplay-unity-mcp
- License:MIT
- Unity 版本:2022.3+
后面会陆续写一些更具体的使用模式------比如怎么用 AI 批量调整美术资源、怎么让 AI 帮你跑 PlayMode 回归、怎么写自己的 ToolProvider 扩展更多工具。如果你在用过程中遇到具体场景搞不定,欢迎在评论或 issue 里抛过来。