
最近我用一个空文件夹试了遍 Claude Code MCP 的组合先建了一个 Unity 2D 项目然后让 AI 从零写出角色控制、敌人生成、UI 计分和重开逻辑最后 Build 出一个能双击运行的小游戏。关键不是那几段代码而是 AI 第一次能真正“驻扎”在游戏项目里通过 MCP 协议直接操控 Unity 编辑器把“生成代码——导入资源——运行调试”的闭环跑通。这篇就写我走通的路径以及踩过的坑。1. 这个项目到底是怎么玩转的1.1 项目的真实内核不是“AI 自动写代码”而是“AI 接管了 Unity 的输入管线”先讲本质。空文件夹之所以能变成可玩游戏是因为 Unity 项目本质上就是一组文件C# 脚本、场景文件、预制体、资源导入配置、包管理清单。任何一个文件变更只要 Unity 编辑器还在监控目录都会自动编译、重新导入、刷新编辑器状态。所以理论上如果有一个 AI 能够精准地创建和修改这些文件再把指令送进 Unity 的编辑器进程里就能“凭空”搭出一个游戏。Claude Code 做的正是这件事。它不止是生成代码片段而是能在终端里读写文件、执行命令、调用外部工具。而 MCPModel Context Protocol就是那条外部工具通道——我通过一个轻量的本地服务把 Unity 编辑器暴露成一组语义化工具Claude Code 需要创建场景对象时就调用“创建物体”工具需要刷新资源时就调用“重新导入资源”工具选择权在 AI执行权在工具。你可能要问这和直接用 AI 聊天窗口复制代码有什么本质区别区别在于闭环。聊天窗口里你拿到代码还要自己建文件、放目录、挂组件、点运行而现在 AI 的判断结果会直接作用在 Unity 项目上报错信息也能从编辑器日志里回流到对话里形成“需求→生成→执行→反馈→修复”的循环。这个循环一旦转起来游戏从零到可玩就不是“写代码”的问题而是“AI 如何理解 Unity 工作流”的问题。1.2 为什么选择“空文件夹”作为起点Unity 项目不是靠“新建项目”按钮创建出来的吗其实那个按钮做的事就是在磁盘上铺一个标准目录结构。如果不通过编辑器创建空文件夹也可以被 Unity 识别只要补上必要的目录和工程设置。但实操中更稳的方式是先用 Unity 创建一个 2D 空项目然后把项目路径交给 Claude Code让它在这个基础上自由发挥。标题说“空文件夹”指的不是字面意义上的零文件而是项目里没有任何业务代码和资产一切从零生成。我刻意没准备任何素材连主角都是用 Unity 内置的 2D Sprite 加一个正方形图片生成的。这样能测试 AI 到底能不能从空白项目里搭建完整玩法。事实证明复杂的东西它会翻车但基础玩法的骨架完全没有问题物体移动、碰撞、生成、UI 更新、重开这些常规内容只要把约束说清楚它产出质量非常高。1.3 这次我最终得到的东西为了让“能玩”有个清晰定义我设置了三条验收标准一是玩家能通过按键控制角色二是游戏里有失败条件碰到障碍物就会结束三是有分数和重开按钮。整体做下来AI 一共生成了大约 7 个 C# 脚本、1 个场景配置和若干界面逻辑中间手动改了 2 个 Bug最终 Build 出了一个不到 20MB 的 Windows 可执行文件跑得起来也玩得顺手。后面我会把这 7 个脚本的分工和生成过程拆开讲方便你理解它为什么能成功以及哪一步最容易失败。2. 工具链拆分Claude Code、MCP 和 Unity 各自在干什么2.1 Claude Code 的定位一个住在项目目录里的 AI 助理Claude Code 本质上是一个命令行环境的 AI 代理它拿到项目文件夹路径后可以直接读取文件列表、打开文件、修改代码、运行终端命令。和网页式对话不同它没有“临时上下文”的错觉它会主动去查看项目当前实际状态再决定下一步动作。比如我告诉它“看看 Assets 目录下都有什么”它会真去列出文件而不是凭空推测。这让它特别适合 Unity 项目。因为 Unity 项目里报错信息、脚本文件名、场景对象名都是高度上下文敏感的AI 如果不知道“你的 PlayerController.cs 文件里类名和文件名是否一致”它生成的代码就可能直接编译失败。Claude Code 的目录感知能力正好把这类问题压到了最低。它还能执行 Unity 的批处理命令所以即便 MCP 没接通它也能通过命令行完成一部分构建工作。2.2 MCP把 Unity 编辑器变成 AI 可以调用的“工具集合”MCP 全称 Model Context Protocol简单理解就是给 AI 开了一份标准化的“工具菜单”。服务端这里就是连接 Unity 的本地程序声明自己有哪些工具每个工具叫什么名字、需要什么参数、返回什么数据客户端Claude Code拿到菜单后在对话里决定“要不要调用、传什么参数”。这很像计算机世界的 USB-C 接口——只要大家都遵守同一个协议任何一个模型都能无缝接上不同的编辑器。我用的 Unity MCP 服务暴露了大概 8 个工具本质都是把 Unity 编辑器操作封装成可调用函数工具名作用关键参数list_files列出项目文件判定存在性路径read_file读取脚本内容检查当前代码文件路径create_csharp_script在指定目录下生成 C# 脚本脚本名、目录、代码正文refresh_assets强制 Unity 重新导入资源无load_scene打开指定场景场景路径set_play_mode进入/退出 Unity 播放模式true/falseget_unity_log取最近一屏编辑器日志最大行数save_scene保存当前场景场景路径在 MCP 协议里工具调用是 JSON-RPC 格式。Claude Code 发送一个带有工具名和参数的请求我本地的小服务收到后转换成 Unity 编辑器 API 调用再返回执行结果。整个过程 AI 看到的不是底层 API而是人类可读的操作结果“已创建 PlayerController.cs”“已进入播放模式”“日志出现 NullReferenceException”。以 refresh_assets 为例一次典型交互大概是下面这样{ jsonrpc: 2.0, method: tools/call, params: { name: refresh_assets, arguments: {} } }返回则是{ jsonrpc: 2.0, result: { content: [ { type: text, text: AssetDatabase.Refresh() 执行完成新脚本已导入 } ] } }不用写死每一个 Unity APIMCP 把“刷新资源”这件事包装成了 AI 能直接理解的命令。这也是整套方案里最值得花时间理解的一环。2.3 和“直接让 AI 生成整段工程”的对比也有更省事的路线比如让 AI 一口气生成完整 Unity 工程文件或者把 Unity 的 AI 插件接在编辑器里。我试过前者结果惨不忍睹手写场景 YAML 稍有不慎就会让资源文件损坏AI 还会生成一堆 Unity 根本不存在的 API。MCP 路线的优势在于AI 只负责生成代码和决策真正让 Unity“认账”的动作都通过编辑器自己完成——刷新资源、保存场景、读取日志每一步都是真实编辑器的行为。接上这三层关系后你大概明白整个系统怎么回事了。下一节开始进入实操。3. 实操记录从空文件夹到能玩的小游戏3.1 先把 Unity 项目目录调教成“AI 能理解的结构”实操第一步还是绕不开 Unity 编辑器。完整流程打开 Unity Hub选择 2D 项目模板项目名用英文路径选一个没有空格的纯英文目录。不要为了炫耀而跳过这一步因为 Clude Code 对路径空格和中文支持虽然没问题但 Unity 的某些内置工具对非 ASCII 路径相当敏感这纯属给自己挖坑。项目建好之后先手工做三件事第一在 Assets 下建好 Scripts、Scenes、Prefabs 三个文件夹让 AI 知道文件往哪放第二创建一个空场景并保存为 Main.unity让 AI 有明确的场景入口第三打开 Project Settings 里的 Player 设置把公司名和产品名改成英文避免 Build 时告警。这三件事做完再把项目根目录完整路径交给 Claude Code。这里有个个人习惯想分享我不会让 AI 直接去访问整个磁盘上的所有文件而是给它一个清晰边界——项目根目录就是工作区所有操作都在这个目录内完成。边界清晰AI 犯方向性错误的概率大幅下降。3.2 配置 MCP Server给 AI 装上操控 Unity 的那只手MCP Server 我一开始想自己写后来发现没必要直接用社区维护的 Unity MCP Server 就能覆盖基础场景。安装方式不复杂在自己的项目目录下创建一个 JSON 配置文件把 MCP Server 的启动命令填进去让 Claude Code 知道怎样拉起这条本地通道。配置大致长这样{ mcpServers: { unity: { command: npx, args: [-y, unity-mcp-server], env: { UNITY_PROJECT_PATH: /绝对路径/你的项目 } } } }提示不要在 MCP Server 的启动目录里放中文或空格否则少数情况下进程会起不来。别问我怎么知道的——我在这里浪费了二十分钟。配置完成并重启 Claude Code 后对话里输入“列出当前可用的 MCP 工具”它会返回类似 2.2 节那张工具表。如果你看到空列表先回终端确认本地进程有没有启动再去查 Unity 编辑器是否处于打开状态。很多 MCP 工具的刷新指令依赖编辑器进程存在编辑器没开工具返回的就是一堆超时而不是明确报错。如果你恰好有时间也可以自己写一个十几行的极简 MCP Server协议核心就是“读 JSON-RPC 请求调用函数返回文本结果”。下面是一个思路示意不需要完整实现# 极简 MCP 服务只处理 refresh_assets 一个工具 import json, sys def handle_call(name, args): if name refresh_assets: # 这里调用 Unity Editor 的刷新接口 return AssetDatabase.Refresh() 完成 if name create_csharp_script: return f已创建脚本 {args.get(script_name)} return f未知工具: {name} for line in sys.stdin: req json.loads(line) if req.get(method) tools/call: result handle_call(req[params][name], req[params].get(arguments, {})) sys.stdout.write(json.dumps({jsonrpc: 2.0, result: result, id: req.get(id)}) \n) sys.stdout.flush()这种实现不会比任何现成方案差因为你最清楚项目需要暴露哪些操作。自写服务的额外收益是你能在日志里清楚地看到 AI 每一步到底调了什么、传了什么参数排查问题非常直观。3.3 让 AI 生成第一版脚本和场景提示词该怎么给我见过很多人让 AI“生成一个游戏”然后抱怨它写得太泛。正确的做法是给 AI 一份“验收清单”而不是一个愿望。我第一轮提示词是这样的我们做一个 2D 躲避小游戏。玩家用左右方向键和空格键控制方块移动跳跃障碍物从右侧自动生成并左移碰到障碍物游戏结束。请先创建 PlayerController.cs要求使用角色控制器脚本并包含跳跃重力系数、水平移动速度两个可调参数。生成后调用 MCP 工具刷新资源。不要一次让它生成所有脚本先聚焦一个最关键的文件。等 PlayerController 编译通过、挂载到场景物体上再继续下一步。原因是 Unity 编译错误会一票否决整个程序集如果一开始就让 AI 生成了 7 个文件任何一个类名不一致都会让所有代码一起失效排查起来极其痛苦。脚本生成之后AI 需要调用 refresh_assets 触发 Unity 重新导入再打开场景把脚本拖到场景里的 Player 对象上。这一步在不同 MCP 实现里有差异有的能直接通过内部 API 挂载组件有的只能生成脚本手动挂载还需要你操作。我们这套方案里AI 会自动调用一个“挂载组件”工具它内部封装了 Unity 的 AddComponent 逻辑。如果不想依赖这个高级工具也可以退一步你自己在编辑器里把脚本拖到物体上再回来告诉 AI“已挂载”不会影响整体流程。PlayerController 的最终版长这样代码本身不稀奇但它证明了 Claude Code 能遵循 Unity 的 MonoBehaviour 生命周期规范using UnityEngine; public class PlayerController : MonoBehaviour { public float moveSpeed 6f; public float jumpForce 10f; public float gravityScale 2.5f; private Rigidbody2D rb; void Start() { rb GetComponentRigidbody2D(); rb.gravityScale gravityScale; } void Update() { float move Input.GetAxisRaw(Horizontal); rb.velocity new Vector2(move * moveSpeed, rb.velocity.y); if (Input.GetKeyDown(KeyCode.Space)) { rb.velocity new Vector2(rb.velocity.x, jumpForce); } } }这段代码生成后立刻通过 MCP 刷新Unity 没有报错。不要小看这个结果如果 AI 没有“看到”项目用的是 Rigidbody2D 而不是 Cube它很容易把碰撞检测写成 3D 版本。3.4 场景文件最不建议 AI 手写 YAML 的地方场景文件是 Unity 里最容易被 AI 搞坏的部分。我第一版让 AI 直接生成 Main.unity它确实生成了也能打开但等我加了物体、保存场景后文件冲突直接把整个场景搞到无法解析。后来学乖了场景文件由 Unity 自己维护AI 只通过 MCP 工具做增量操作比如“创建一个空物体”“给物体添加 SpriteRenderer”“给物体挂脚本”。这样 Unity 写入的 YAML 结构永远是它自己认得的AI 只负责语义层的改动。所以你在实操里不要试图绕过工具直接写 .unity 文件尤其是包含大量对象 ID 和引用 ID 的场景。哪怕你只是改了一个字段名也容易让 Unity 的序列化器找不到引用。正确姿势是让 AI 调用“创建物体”工具然后 MCP 在编辑器里执行真实操作实现“把物体加到当前场景”。我让 AI 搭建场景时它按顺序做了几件事创建 Player 空物体并挂上 SpriteRenderer 和 PlayerController创建一个空物体挂上“障碍物生成器”脚本在 Canvas 下创建计分 Text 和结束面板。每完成一步它都会调 save_scene 保存。这样 Unity 有最完整的序列化状态AI 也不会写飞。3.5 关键反馈循环日志返回AI 才能自我修复游戏跑起来之前几乎注定会报错。NullReferenceException、组件没赋值的错误、Input 类在旧输入系统被禁用……每一个都是 AI 容易犯的错误。但 MCP 把日志回路打通之后这些错误就不再是你和 AI 之间的盲区了。我印象最深的一次循环AI 生成障碍物生成脚本后进入 Play 模式游戏一运行就报“Stack.Collider 为空”。Claude Code 看到 get_unity_log 返回的日志后自己判断出是预制体上没有加 Collider2D然后调用 MCP 工具给障碍物预制体添加了碰撞体再自动退回到播放模式重测。整个过程我在旁边只是读了日志没有手动碰任何代码。用表格还原这一段完整循环步骤谁的输入发生了什么1我让 AI 实现障碍物生成和碰撞2AI生成 Spawner.cs 和 Obstacle.cs3MCP刷新资源、进入播放模式4Unity 日志返回空引用异常Collider 为 null5AI读取异常定位到“预制体缺 Collider2D”6MCP给预制体添加 Collider2D 组件、保存7AI声明修复完成请我验收这种“日志驱动修复”非常有效前提是你要在 MCP 工具里有可靠的日志获取能力。如果没有这个工具AI 就只能瞎猜和用聊天窗口写代码没区别了。更进一步你可以为项目配备测试脚本AI 在每次修改后都会触发一次“自动化冒烟测试”启动游戏模拟输入读取输出再把结果回传。这样它的自我纠错周期会更短。3.6 Build 成可执行文件空文件夹变成“能玩的游戏”的最后一公里“能玩”的定义不只是编辑器里能按 Play而是能独立运行。这一步我也让 AI 试了一下。它在 Build Settings 里启用当前场景选择 Windows 平台然后调用 Unity 批处理模式触发一次构建。构建过程跑了大概三分钟失败了一次原因是场景没被加入 Build 列表AI 自己从日志里读到了错误调用“加入 Build 场景”工具修正后重新构建成功。到今天我的项目根目录下多了一个 Build 文件夹里面是一个可以双击运行的 exe。空文件夹到这个文件之间的距离隔着一套 Agent、一个 MCP 协议桥和几十轮对话。值得强调的是构建这一步和 MCP 的关系已经不大因为它只需要命令行参数Unity 本身支持批处理模式执行构建所以 AI 通过终端直接执行也能完成。但 MCP 的好处是能让 AI 在“构建失败时自动看到准确错误”而不是靠猜。4. 避坑指南与问题排查实录4.1 高频问题速查表下面这些坑是我在过程中真正撞过的整理成表现象真实原因解决办法脚本生成后 Unity 没有反应AssetDatabase 未刷新调用 refresh_assets 工具或手动回编辑器刷新所有脚本同时编译失败某文件类名和文件名不一致让 AI 对照报错逐文件检查不要整体重写MCP Server 启动失败路径含空格或非 ASCII项目放在纯英文路径重启 Claude Code场景打开后物体缺失手动改 YAML 导致序列化错误不要手写 .unity通过 MCP 工具操作场景进入 Play 模式卡死AI 创建了无限循环查看日志获取堆栈让 AI 修复后重测构建报错“场景未加入”Build Settings 里没有场景通过 MCP/API 把场景加入 Build 列表生成代码用错了 Input API新旧 Input System 不匹配在提示词中明确“使用旧版 Input Manager”这里最容易被忽视的是最后一条。Unity 不同版本的输入系统差别很大如果不在最开始告诉 AI“项目使用 Input Manager 还是新的 Input System 包”它会自己“智能”选一个然后代码在项目里编译不过。这类错误不用改逻辑只改 API 名称很浪费上下文。4.2 让 AI 工作流更稳的四个经验第一把 Unity 项目的关键信息写成一个PROJECT_CONTEXT.md放在项目根目录内容包含 Unity 版本、用的是 2D 还是 3D 管线、输入系统类型、常用目录约定、脚本命名规范。Claude Code 读取项目文件时会优先看到这个文件后面每一步都不需要重复解释背景。我自己用的模板大致是这样# Unity 项目上下文 - 渲染管线2D / Built-in - 输入系统旧版 Input Manager - 命名空间无使用全局脚本 - 目录约定Scripts/ 放脚本Scenes/ 放场景 - 代码规范公开字段用于调参私有字段用 _ 前缀第二要求 AI 每次只改一个文件改完立刻调用刷新工具并等待编译结果再继续下一个任务。并行修改多个文件看着快实际遇到编译错误时AI 会像无头苍蝇一样不知道哪个文件的问题。这个习惯救了我很多次。第三熟练使用“停止并重新描述”的纠偏手段。当 AI 连续两轮都在同一个坑里打转时不要让它继续自行尝试而是直接在对话里把它刚才生成的代码路径指出来告诉它“当前状态是什么、期望是什么、请先暂停生成分析日志再动”。它往往很快就能回来。第四做好版本管理。AI 每完成一个里程碑就在项目根目录执行一次 Git 提交。这不只是为了防呆而是让你能随时把项目回滚到“可玩状态”。我见过 AI 把可用代码改坏如果没有版本回滚你就只能手动一行行找差异非常痛苦。4.3 我给这套方案打几分如果只看最终结果这套组合给独立开发者的效率加成是真实存在的。但如果你期待它像魔法师一样口述需求就自动产出 3A 游戏趁早醒醒。它对“工程量可控、结构清晰、有标准反馈机制”的小项目极其适用对大型复杂项目AI 仍然会频繁产生架构层面的臆测你的人肉审查压力不会比手写代码少多少。我的结论是它最适合做原型验证和小型工具不适合在没有经过训练的情况下直接做商业游戏项目。5. 还能怎么扩展从“小游戏”到“游戏工作流”5.1 玩法内容方向自动生成关卡、UI 和动画状态机既然小 demo 能跑通下一步自然是往真实游戏需求上靠。比如用 AI 生成 Tilemap 布局把关卡设计从“手摆格子”改成“JSON 描述 AI 执行”或者让 AI 根据设计师提供的素材清单自动生成预制体自动挂上碰撞体和动画组件再进一步让 AI 读取策划表格在表格里配置怪物刷新表然后由 MCP 工具自动生成对应的 Spawner 配置。这些都是同样路径的延伸。我第二个试验是一个自动生成的跑酷关卡我用一个表格定义了 20 段路面的障碍物密度和道具位置AI 读取表格后调用 MCP 的“生成 Tilemap 瓦片”工具逐段铺设。最终生成的关卡在编辑器里同时呈现不需要手摆一块砖。这条路对程序化内容非常友好因为 AI 本来就擅长读结构化数据、生成重复性高的内容。5.2 工具链方向让 AI 帮你自己写编辑器扩展我更看好的是 AI 生成编辑器工具。Unity 本身就是个高度可扩展的编辑器C# 脚本可以在编辑器模式里拖窗口、按钮、自定义 Inspector。MCP 可以把这些编辑器窗口也暴露成工具甚至 AI 可以直接生成一个“批量重命名工具”“一键生成寻路网格工具”。这对管线自动化的帮助比单纯生成游戏玩法代码更稳定、更可控因为编辑器工具逻辑封闭、输入输出明确AI 不容易跑偏。实操时你只需要两步第一步让 Claude Code 生成 Editor 文件夹下的脚本第二步把脚本里需要暴露的功能封装成 MCP 工具。这样 AI 不仅会写游戏还会写“生产游戏时用的工具”性质就变了。5.3 谁来用这套方案最划算我的体感这套方案最适合两类人。第一类是懂游戏设计但代码一般的独立开发者他们能把需求拆得很细AI 刚好能快速实现原型验证玩法好不好玩。第二类是技术负责人用来做技术预研和工具链自动化省去大量重复搭建工作。纯新手建议不要一上来就依赖 AI因为 AI 报错后的反馈循环仍然需要你理解 Unity 的基本运作方式你至少要能分清“编译错误”“运行错误”“逻辑错误”否则日志回传反而会让你更迷茫。最后聊一个我从这套流程里带出来的个人习惯不要让 AI 一口气把整个游戏做完而是把“能玩”拆成多个里程碑每个里程碑都实际运行验证一次。空文件夹变成能玩的游戏看起来很神奇其实背后是很多次“生成-验证-修正”的循环。MCP 解决的是 AI 和 Unity 之间那道看不见的墙但墙推倒之后你作为开发者要做的事情并没有消失——你变成了一个验收者、一个架构师、一个知道什么是“够玩”的产品经理。这个角色转变才是这套工具链最有意思的地方。