从一句话到可玩原型:用 funplay-unity-mcp 让 AI 搭起完整游戏循环

前三篇的尺度都是"一个机制":调一次跳跃手感、给一个机制写回归测试。这篇往上跳一格------不再是单个机制,而是一个完整、能玩、有头有尾的循环

需求就一句话,丢给接了 funplay-unity-mcp 的 Claude Code:

做一个金币收集的平台跳跃小游戏:角色能移动和跳跃,跳上几个平台收集所有金币就算赢,掉下去自动重生,按 R 重开。

下面是它实际做出来的东西,以及做的过程里值得说的点。

先看结果

开局是 Coins: 0 / 6,玩家(红块)在地面,金币散在地面和三层平台上。跳上三层平台、把六个金币全部收集之后,胜利横幅弹出、金币全部消失:

中间的过程------三个脚本、一段场景搭建、一次自动通关验证------全部由 AI 通过 MCP 工具完成。

AI 怎么拆这个需求

一个关键的分工,是它自己分清了两类工作

  • 持久的游戏逻辑 → 写成 .cs 脚本文件,需要 Unity 编译。角色控制、金币、计分这种"游戏运行时一直存在"的行为属于这类。
  • 一次性的场景编排 → 用 execute_code 即时执行,不落文件、不触发编译。"在这些坐标摆地面/平台/金币、配好材质、放好相机"属于这类。

这个区分很重要:如果把摆场景也写成脚本,会污染项目、还要等编译;如果把游戏逻辑塞进 execute_code,退出运行就没了。AI 分得很清楚。

三个脚本(持久逻辑)

PlayerController.cs ------ 移动 + 跳跃,复用了前几篇调好的"下落额外重力"手感:

csharp 复制代码
[RequireComponent(typeof(Rigidbody))]
public class PlayerController : MonoBehaviour
{
    public float moveSpeed = 5f;
    public float jumpForce = 6f;
    public float fallGravityMultiplier = 2.5f;
    public float groundCheckDistance = 0.55f;
    Rigidbody _rb;
    Vector3 _spawn;

    void Awake() { _rb = GetComponent<Rigidbody>(); _rb.constraints = RigidbodyConstraints.FreezeRotation; _spawn = transform.position; }
    bool IsGrounded() => Physics.Raycast(transform.position, Vector3.down, groundCheckDistance);

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && IsGrounded())
        {
            _rb.velocity = new Vector3(_rb.velocity.x, 0f, _rb.velocity.z);
            _rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
        }
        if (transform.position.y < -5f) Respawn();   // 掉出地图
    }

    void FixedUpdate()
    {
        float h = Input.GetAxisRaw("Horizontal"), v = Input.GetAxisRaw("Vertical");
        var dir = new Vector3(h, 0f, v);
        if (dir.sqrMagnitude > 1f) dir.Normalize();
        _rb.velocity = new Vector3(dir.x * moveSpeed, _rb.velocity.y, dir.z * moveSpeed);
        if (_rb.velocity.y < 0f)
            _rb.AddForce(Physics.gravity * (fallGravityMultiplier - 1f), ForceMode.Acceleration);
    }

    public void Respawn() { _rb.velocity = Vector3.zero; _rb.position = _spawn; transform.position = _spawn; }
}

Coin.cs ------ 旋转 + 被玩家触碰即收集:

csharp 复制代码
public class Coin : MonoBehaviour
{
    public float spinSpeed = 120f;
    void Update() => transform.Rotate(Vector3.up, spinSpeed * Time.deltaTime, Space.World);
    void OnTriggerEnter(Collider other)
    {
        if (other.GetComponentInParent<PlayerController>() != null)
        {
            if (GameManager.Instance != null) GameManager.Instance.Collect();
            Destroy(gameObject);
        }
    }
}

GameManager.cs ------ 计分、胜负、重开,HUD 直接用代码生成(不用手摆 Canvas):

csharp 复制代码
public class GameManager : MonoBehaviour
{
    public static GameManager Instance;
    public int total;
    int _collected;
    Text _label, _banner;

    void Awake()
    {
        Instance = this;
        total = FindObjectsByType<Coin>(FindObjectsSortMode.None).Length;  // 自动数场景里的金币
    }
    void Start() { BuildHUD(); Refresh(); }
    void Update() { if (Input.GetKeyDown(KeyCode.R)) SceneManager.LoadScene(SceneManager.GetActiveScene().name); }

    public void Collect()
    {
        _collected++;
        Refresh();
        if (_collected >= total && _banner != null) _banner.text = "YOU WIN!\n按 R 重开";
    }
    void Refresh() { if (_label != null) _label.text = $"Coins: {_collected} / {total}"; }
    // BuildHUD() 用代码建 Canvas + 两个 Text,字体取 Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf")
}

场景编排(一次性)

写完脚本、request_recompile 等编译完之后,AI 用一段 execute_code 把整个场景搭出来:新建空场景、放地面、三层平台、玩家(加 PlayerController,靠 [RequireComponent] 自动带上 Rigidbody)、六个金币(缩小的方块 + isTrigger 碰撞体 + Coin 脚本)、一个空的 GameManager、摆好相机和光照,最后存成 PlayablePrototype.unity

这一段不写进任何脚本文件------它是"布置这一个场景"的动作,跑完即弃。

让 AI 自己玩通关来验证

搭完不等于做对了。前一篇的回归测试思路在这里复用:让 AI 自己把它玩一遍,用客观信号确认闭环成立

真人玩是 WASD + 空格。但要在编辑器失焦、无人操作的情况下做确定性验证,AI 走了另一条更干净的路:把物理切到脚本步进模式,把玩家依次"瞬移"到每个金币位置,每次手动 Physics.Simulate(0.02f) 步进几帧触发 OnTriggerEnter

csharp 复制代码
Physics.simulationMode = SimulationMode.Script;
foreach (var coin in Object.FindObjectsByType<Coin>(FindObjectsSortMode.None))
{
    rb.position = coin.transform.position;
    rb.velocity = Vector3.zero;
    for (int i = 0; i < 3; i++) Physics.Simulate(0.02f);   // 同步步进,触发 trigger
}
Physics.simulationMode = SimulationMode.FixedUpdate;

跑完读 HUD:

复制代码
开始自动通关,金币数=6
通关后:HUD='Coins: 6 / 6'  banner='YOU WIN! 按 R 重开'

收集 → 计分 → 胜利整条链路成立。这比"看起来能玩"强------它是被一段确定性脚本验证过的。

这一篇难在哪

前几篇都是单点:一个 Rigidbody 参数、一个 raycast 距离。这篇第一次要让五个子系统同时对上

  • 输入Input.GetAxisRaw / GetKeyDown 读移动和跳跃
  • 物理:Rigidbody 速度控制 + 地面检测 + 下落额外重力
  • 触发 :金币 isTrigger + OnTriggerEnter + 正确识别"碰到的是玩家"(GetComponentInParent<PlayerController>
  • UI:代码生成 Canvas / Text,并在收集时刷新
  • 场景管理 :胜利判定、SceneManager.LoadScene 重开、掉落重生

任何一个环节错了,循环就不闭合------金币不消失、分数不动、赢了不提示、重开重置不干净。AI 一次把这五个对上,靠的是它能在同一个上下文里既写脚本、又搭场景、又跑验证,中间不用人来回翻译。

几个它处理得对、但新手容易栽的细节:

  • HUD 用 Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf") 取内置字体------新版 Unity 把老的 Arial.ttf 改名了,直接 new Text 不给字体会渲染不出来。
  • GameManager.totalAwakeFindObjectsByType<Coin> 自动统计,而不是硬编码 6------加减金币不用改代码。
  • 金币识别玩家用 GetComponentInParent,避免玩家身上有子碰撞体时识别失败。

诚实地讲:这是原型,不是游戏

这套东西能玩、闭环成立,但离"游戏"还很远,AI 也替代不了后面那段:

  • 美术全是色块。红方块当角色、黄方块当金币------原型阶段够用,但"做成游戏"需要模型、动画、特效,那是另一回事。
  • 没有音效、没有反馈。收集金币该有"叮"的一声、一个粒子、一下镜头微动------这些"juice"是手感的一半,目前一点没有。
  • 没有关卡设计。六个金币的位置是我让它随便摆的,不是设计过的难度曲线。"跳起来爽不爽、关卡有没有节奏"必须人来调。
  • 平衡靠手调jumpForce=6moveSpeed=5 是拍脑袋的值,到底合不合适得真人玩着调(就像第二篇那样)。

所以这一篇的定位很清楚:AI 能极快地把一个可玩的骨架搭起来并验证它闭环,让你跳过"从 0 到能跑"那段最枯燥的体力活,直接进入"它好不好玩"的创作环节。骨架是它的,灵魂还是你的。

完整产物

下一篇继续往上爬:让 AI 程序化生成一套平台关卡,再让它自己从起点跳到终点确认这关能通------生成 + 自验证的闭环。

相关推荐
X54先生(人文科技)1 小时前
《元创力》纪实录·卷宗2.1刻舟求剑:一场关于“唯一解”的范式战争
人工智能·架构·开源·零知识证明
碳基硅坊1 小时前
llama.cpp本地部署Qwen3.6-27B
人工智能·llama·推理加速·qwen3.6-27b
钓了猫的鱼儿1 小时前
基于深度学习+AI的卷心菜目标检测与预警系统(Python源码+数据集+UI可视化界面+YOLOv11训练结果)
人工智能·深度学习·目标检测
大象说1 小时前
从NLP特征匹配底层逻辑拆解知网AI检测的实际优缺点
人工智能
私域合规研究2 小时前
法律护航携手天道异业达成战略合作
大数据·人工智能
咖啡星人k2 小时前
从需求到交付:我用MonkeyCode的AI Agent完成了一个React数据看板
前端·人工智能·react.js·monkeycode
Nayxxu2 小时前
Claude API 企业落地路线图:POC、灰度、监控、缓存、上线
人工智能·claude
汽车仪器仪表相关领域2 小时前
南华 NHA-604/605 汽车排放气体测试仪:国六b全适配高精度便携检测设备
大数据·人工智能·功能测试·深度学习·安全·fpga开发·压力测试
媒介发稿小能手2 小时前
全链路透明可控API接口赋能|GEO媒介平台解锁可量化增长
大数据·人工智能