mcpField
P
Patina Unity MCP

Patina Unity MCP

本地服务
github.com/taygunsavas开发工具45 天前更新

关于 Patina Unity MCP

Patina Unity MCP 是配有 C# 桥接程序的 Rust MCP 服务,可控制 Unity Editor。它让 AI 编码工具通过本地连接检查和编辑场景、资源、脚本等。

主要功能

  1. 01检查和编辑场景层级
  2. 02创建和修改 GameObject
  3. 03管理预制件和资源
  4. 04读取和写入脚本及组件
  5. 05编译脚本并检查错误
  6. 06一键配置已检测到的客户端

适用场景

  1. 01通过 AI 编码工具检查 Unity 场景
  2. 02创建场景对象或调整其变换
  3. 03编辑预制件资源和材质
  4. 04检查脚本编译错误

MCP 相关

Rust 服务将 Unity Editor 命令作为 MCP 工具提供,并通过本地 TCP 桥接与编辑器通信。客户端通过 stdio 连接服务。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"taygunsavas-patina-unity": {
"command": "npx",
"args": [
"-y",
"com.taygunsavas.patina-unity-mcp"
]
}
}
}
启动命令npx -y com.taygunsavas.patina-unity-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmcom.taygunsavas.patina-unity-mcp1.2.2

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Patina

npm version MCP Registry Glama MCP server Indexed on TensorBlock MCP Index License: MIT

通过任何 MCP 宿主控制 Unity Editor。只需安装一个包、点击一次,你的 AI 助手便能查看场景、创建对象并与控制台交互。

Patina 是一个 Rust MCP 服务,配有 C# Unity 桥接组件。它通过本地 TCP 通道,将你喜爱的 AI 编码工具直接连接到 Unity Editor,无需手动配置。

为什么选择 Patina?

  • 一键设置。 安装 UPM 包,点击一个按钮,即可自动配置所有受支持的宿主。
  • 无需 Rust。 发布包附带适用于 Windows、Linux 和 macOS 的预构建二进制文件。安装即可使用。
  • 为速度而打造。 Rust 辅助进程让 MCP 层保持快速轻量,同时 Unity 仍在主线程上运行。
  • 支持多个宿主。 可与 Claude Code、Cursor、VS Code、Gemini CLI、JetBrains Rider、Codex CLI 等配合使用。

工作原理

MCP Host  <-- stdio -->  Patina Server  <-- local TCP -->  Unity Editor

宿主通过 stdio MCP 启动 Rust 二进制文件。Rust 服务通过本地回环 TCP 桥接组件,将工具调用转发到 Unity。Unity 在主线程上执行调用并返回结果。

快速开始

1. 安装 Unity 包

在 Unity 中,打开 Project Settings > Package Manager,添加一个作用域注册表,然后按名称安装包。

作用域注册表:

字段值
名称npmjs
URLhttps://registry.npmjs.org
作用域com.taygunsavas

然后打开 Package Manager(Window > Package Manager),点击左上角的 + 图标,选择 Add package by name...,并输入:

com.taygunsavas.patina-unity-mcp

注册表发布版本会在发布工作流中签名,以便通过 Unity Package Manager 验证。

或者,打开 Package Manager,点击 + 图标,选择 Add package from git URL...,并输入:

https://github.com/taygunsavas/patina-unity-mcp.git?path=/unity-package

Patina 以完整的 Unity 包制品形式分发,其中包含编辑器代码、Plugins/<platform>/ 下的 Rust 原生运行时二进制文件,以及导入所需的 Unity 元数据。最终用户无需安装 Rust 工具链,也无需克隆此仓库。

2. 运行一键设置

打开 Window > Patina Unity MCP,然后点击 One-Click Setup。

设置流程会验证二进制文件、启动 Unity 桥接组件、自动配置所有检测到的宿主、替换过期条目,并在需要时显示重启提示。

Patina 会将宿主配置写入稳定的用户级运行时路径,而不是 Unity 包缓存中的项目级路径。更新包时,Unity 编辑器包会自动刷新受其管理的运行时,因此受支持的 MCP 宿主无需仅因包缓存路径发生变化而重新配置。

3. 开始构建

打开你的 MCP 宿主并尝试:

  • “在 Unity 控制台中输出 hello”
  • “显示场景层级结构”
  • “在位置 0, 2, 0 创建一个立方体”

可用能力

Patina 保持精简的 MCP 接口,避免宿主将所有 Unity 命令架构加载到上下文中。Agent 应使用:

MCP 工具功能
patina_capabilities搜索或浏览 Unity 命令目录;仅按需请求特定命令的架构
patina_call使用 JSON 参数执行目录中的命令
patina_health检查 Patina 版本、命令数量、桥接端口、可选的 Unity 编辑器状态以及桥接诊断信息

以下 87 条命令可通过 patina_capabilities 和 patina_call 使用。

场景
工具功能
get_hierarchy以嵌套 JSON 格式获取活动场景的 GameObject 树;支持 max_depth 和 name_filter
get_scene_info获取活动场景的元数据(名称、路径、构建索引、根对象数量、脏状态);传入 include_all_scenes 可获取所有已加载场景的信息
open_scene按相对于项目的路径打开场景;mode 可设为 single(默认)或 additive
save_scene保存活动场景或任何已加载的场景;支持“另存为”
new_scene创建并保存新场景,可选择创建空场景或包含默认游戏对象的场景
游戏对象
工具功能
create_game_object创建空 GameObject 或内置基元(Cube、Sphere、Capsule、Cylinder、Plane、Quad)
delete_game_object永久删除 GameObject 及其所有子对象
duplicate_game_object复制 GameObject 及其子对象
reparent_game_object将 GameObject 移至新的父对象下;传入 null 可将其提升为场景根对象
get_game_object_info获取指定 GameObject 的完整详情:变换、标签、层以及所有组件属性
set_active_state通过 SetActive() 显示或隐藏 GameObject
set_tag设置 GameObject 的标签(标签必须已在 Tags & Layers 中注册)
set_layer按名称设置层;可选择应用于所有子对象
set_transform一次调用即可设置世界空间或局部空间中的位置、旋转(欧拉角)和/或缩放
组件与属性
工具功能
add_component按简称(Rigidbody)或全限定名称添加组件
remove_component按类型名称移除组件
set_property按名称设置组件的公共字段、可写公共属性或 [SerializeField] 字段(包括继承的成员)
get_game_object_components返回 GameObject 的轻量级组件列表
批量操作
工具功能
batch_set_properties对多个 GameObject 应用 set_property 样式的更改(公共成员或 [SerializeField] 字段)
batch_add_components为多个 GameObject 添加组件
batch_set_transform对多个 GameObject 应用变换更改
预制件
工具功能
create_prefab将场景中的 GameObject 保存为预制件资源
instantiate_prefab在场景中实例化预制件,可选择指定世界坐标位置
get_prefab_info检查预制件资源或场景实例;返回资源类型、覆盖项列表和实例状态
unpack_prefab断开预制件实例的关联;可选 outermost(默认)或 completely
apply_prefab_overrides将所有实例覆盖项应用回磁盘上的源预制件资源
revert_prefab_overrides将预制件实例还原为与源资源一致
list_prefab_components列出预制件资源上的组件类型和实例 ID;也可包含子 GameObject 及其变换路径
edit_prefab_asset对预制件资源执行一批编辑操作(添加/移除组件、添加/移除子对象、设置字段),包括对象引用字段以及 GameObject 级别的 layer、tag、isStatic、name 和 activeSelf;保存后,对修改过的组件运行 OnValidate 并再次保存
open_prefab_stage在 Unity 的预制件阶段中打开预制件资源以供编辑;使用 close_prefab_stage 退出
close_prefab_stage关闭当前活动的预制件阶段;save_changes 参数可在不触发 Unity 阻塞式保存提示的情况下处理未保存的更改,并选择保存或放弃

保存并重新导入后,edit_prefab_asset 会对已保存资源进行反射调用 OnValidate:对于每个受影响 GameObject 上,通过 add_component 或 set_field 修改过的每种类型的组件都会调用该方法;之后会再次保存,从而持久化在那里计算的状态(例如 Netcode NetworkObject 哈希值)。如果 OnValidate 抛出异常,命令仍会成功,结果中会添加 warnings 字符串数组,列出跳过或抛出异常的组件;即使无法加载已保存的预制件,或无法解析跟踪的路径或组件,也会列出。

示例:设置 GameObject 级别的值。

如果省略 component_type,或将其设为 "GameObject" 或 "UnityEngine.GameObject",set_field 会以 GameObject 本身为目标。支持的 field_name 值包括 layer(索引 0-31 或层名称)、tag、isStatic、name 和 activeSelf(预制件根对象的名称会采用资源文件名,因此不允许对根对象设置 name)。add_child 也接受可选的 layer、tag 和 is_static:

{
  "asset_path": "Assets/Prefabs/MyPrefab.prefab",
  "actions": [
    {"action_type": "add_child", "child_name": "Wall0", "layer": "Water", "tag": "Player", "is_static": true},
    {"action_type": "set_field", "transform_path": "Wall0", "component_type": "UnityEngine.GameObject", "field_name": "layer", "value": 5}
  ]
}

示例:设置预制件中的组件引用。

要将序列化字段指向同一预制件内的另一个组件,请传入一个包含 set_field 和对象引用值的 edit_prefab_asset 操作。value 中的 transform_path 会相对于预制件根对象解析,而不是相对于操作自身的 transform_path:

{
  "asset_path": "Assets/Prefabs/MyPrefab.prefab",
  "actions": [
    {
      "action_type": "set_field",
      "component_type": "MyNamespace.MyComponent",
      "field_name": "targetReference",
      "value": {"transform_path": "Container/Button", "component_type": "MyNamespace.TargetComponent"}
    }
  ]
}
资源
工具功能
find_assets_by_type按类型筛选器(t:Material、t:Prefab、t:Texture2D 等)在 Asset Database 中搜索
find_assets_by_name在 Asset Database 中按部分名称匹配搜索
get_asset_info获取资源元数据:GUID、类型、文件大小、标签和导入器设置
create_folder在 Asset Database 中创建新文件夹
move_asset将资源移动到项目相对路径下的新位置
rename_asset就地重命名资源
delete_asset按项目相对路径删除资源
refresh_asset_database触发 AssetDatabase.Refresh;可选择增量刷新或强制重新导入
set_asset_labels替换资源的完整标签列表
材质
工具功能
create_material创建新的 Material 资源;默认使用 URP/Lit
get_material_properties读取所有公开的着色器属性,包括名称、类型和当前值
set_material_property设置着色器属性(浮点数、布尔值、颜色、向量或纹理路径)
assign_material将 Material 指定给特定 Renderer 槽位
脚本
工具功能
create_script根据模板(monobehaviour、scriptableobject、editor_window、plain_class、interface)或原样内容创建新的 C# 脚本
resolve_script_type根据完全限定的 C# 类型解析 MonoScript GUID 和资源路径
force_recompile通过 AssetDatabase.Refresh(ForceUpdate) 触发 Unity 脚本重新编译
compile_and_get_errors触发脚本重新编译并仅返回编译器错误;同时返回 compilationRan、domainReloadObserved 和 reloadCount
get_compilation_errors获取当前编译器错误和警告列表
get_script_content读取项目中脚本文件的内容
get_assembly_types列出特定程序集声明的所有类型
request_script_reload通过 EditorUtility.RequestScriptReload() 请求域重载,并在完成后返回,以便观察重载期间的错误
Scriptable Objects
工具功能
get_scriptable_object读取 ScriptableObject 资源中的序列化字段
set_scriptable_object_field设置一个序列化的 ScriptableObject 字段
验证与运行状况
工具功能
validate_scene扫描当前场景中的质量问题(缺失的脚本引用、为空的序列化字段和损坏的预制件连接)
validate_assets验证单个预制件资源或递归验证整个文件夹,检查缺失的脚本、损坏的对象引用和未赋值的必需序列化字段
get_scene_stats返回当前场景的轻量统计信息(对象数量、组件数量、唯一类型数量、最大深度等)
搜索与查询
工具功能
find_game_objects_by_tag查找具有指定标签的所有活动 GameObject
find_game_objects_by_component查找所有具有指定组件类型的场景对象
find_game_objects_by_layer按名称查找指定图层上的所有场景对象
query_game_objects查找符合组合筛选条件的 GameObject
find_game_objects_by_path按层级路径前缀查找 GameObject
控制台
工具功能
log_to_console向 Unity 控制台输出消息(info、warning 或 error)
get_console_logs读取带有每条记录的 phase 字段(normal、reloadTeardown、reloadStartup)的缓冲控制台条目;可按类型筛选,并受 max_results 限制;包含 reloadWindowEntryCount
clear_console清除所有控制台日志条目
编辑器状态与控制
工具功能
get_editor_state获取当前编辑器标志和主线程响应状态;如果 Unity 未处理编辑器更新,则返回受限的阻塞状态,其中包含 blockedByModalDialogLikely
get_project_settings只读地获取关键项目设置的快照(版本、构建目标、色彩空间、物理重力等)
set_play_mode进入、退出、暂停、取消暂停或逐步推进播放模式
execute_menu_item执行任意编辑器菜单项的完整路径(例如 Assets/Refresh)
get_selection返回当前编辑器选中项(场景对象和/或资源路径)
set_selection将特定 GameObject 和/或资源路径设为编辑器选中项
撤销
工具功能
begin_undo_group打开一个命名的 Unity 撤销组
end_undo_group将操作合并到当前撤销组
undo执行一步或多步撤销
redo执行一步或多步重做
get_undo_stack返回当前撤销和重做堆栈条目名称
构建和播放器设置
工具功能
get_build_settings构建设置快照:当前目标、脚本后端和完整场景列表
set_build_scenes将构建设置中的场景列表替换为按顺序排列的场景路径列表
get_player_settings读取某个构建目标组(Standalone、Android、iOS、WebGL)的播放器设置
set_player_settings写入播放器设置字段;仅更改非 null 字段
set_build_target切换当前构建目标(大型项目中会阻塞主线程)
测试运行器
工具功能
run_tests启动 Unity 测试运行器执行。filter 是测试名称或完整名称中区分大小写的子字符串;若筛选条件未匹配到任何测试,则返回错误。响应包含 runId 和 matchedCount(未提供筛选条件时为 null)
get_test_results返回最近一次测试运行的结果,以及 runId、startedAt 和 finishedAt。运行期间发生域重载时,这些值会重置为 null,结果为空,这表示测试运行已丢失
get_test_list列出可用的 Unity 测试
动画
工具功能
get_animator_info读取 Animator Controller 参数和状态信息
set_animator_parameter在播放模式下设置 Animator 参数
list_animation_clips列出项目中的 AnimationClip 资源

支持的宿主

宿主设置
Antigravity CLI (agy)自动
Claude Code (Anthropic CLI)自动(~/.claude.json)
Claude Desktop自动
Cursor自动
Visual Studio Code自动
GitHub Copilot (VS Code)通过 VS Code 配置关联
Gemini CLI自动
JetBrains Rider / Junie自动
Codex CLI自动

设置窗口还会检测过时条目和缺失的宿主,并提供简洁的 从宿主中移除 Patina 操作。

故障排除

如果 Patina 调用报告 EDITOR_BLOCKED,或提示 Unity 可能正在等待模态对话框,请检查 Unity Editor 是否有保存更改提示或其他阻塞弹窗。Unity 等待用户输入时,Patina 无法安全地运行排队的编辑器命令。处理 Unity 提示后,重试 MCP 命令,或使用 {"include_unity_state": true} 运行 patina_health。

预制件阶段保存对话框

Patina 通过以编程方式响应保存问题,而不是等待模态对话框,来处理已修改的预制件阶段。调用 close_prefab_stage 时,save_changes 参数会直接决定结果:true 保存,false(默认值)放弃更改。这仅适用于该命令调用,不会改变人在手动操作时的 Editor 行为。

模态对话框一旦出现,Unity 主线程就会被阻塞,直到有人关闭对话框。所有排队的命令都会经过同一个被阻塞的线程处理,因此预防才是唯一真正有效的解决方案。对于由 Agent 编写的 Editor 脚本,安全做法是使用 PrefabUtility.LoadPrefabContents 写入预制件,将更改应用到 SerializedObject,使用 PrefabUtility.SaveAsPrefabAsset 保存,然后调用 PrefabUtility.UnloadPrefabContents。这种方式永远不会打开预制件阶段。如果必须打开阶段,请使用 close_prefab_stage 将其关闭。让阶段保持已修改状态并手动调用 StageUtility.GoToMainStage() 会锁定 Editor。

Unity 提供了启动标志 -automated,可在整个进程范围内禁用对话框。对于完全由 Agent 驱动的 Editor,这或许合适;但在人和 Agent 共用同一个 Editor 的混合工作流中,它会带来问题:未保存的更改不会触发提示,某些操作也会被静默取消。Patina 不要求使用 -automated。不使用该标志时,按命令响应对话框也能可靠运行;即使 Editor 是使用 -automated 打开的,也能正常工作。

如需检查当前 Editor 状态和对话框自动化状态,请调用 patina_health,并查看默认输出中的 broker.sessions[].automated;或者传入 {"include_unity_state": true},查看 isAutomatedMode 和 dialogAutomationAvailable。

路线图

阶段重点
阶段 1 ✓核心工具:控制台、层级视图、对象创建
阶段 2 ✓扩展覆盖范围:场景管理、资源操作、组件编辑
阶段 3(当前)分发与覆盖范围:Git URL 安装文档、包布局、发布流水线

本地开发

贡献者源码检出

直接从仓库编辑 unity-package/ 或 rust-server/ 时,请使用此方式:

  1. 将 Unity 指向本地包检出目录。
    • file:<your-clone-path>/unity-package
  2. 构建 Rust 服务。
cd rust-server && cargo build --release
  1. 将当前二进制文件发布到本地开发运行时路径。
# Windows
pwsh -File scripts/publish-dev-runtime.ps1
# macOS / Linux
./scripts/publish-dev-runtime.sh
  1. 在 Unity 中,打开 Window > Patina Unity MCP,启用 Use Local Runtime (Contributor),然后点击 One-Click Setup。

这会使用本地开发运行时而非受管理的打包运行时写入主机配置。每次执行新的 cargo build --release 和 publish-dev-runtime 后,都要重新运行 One-Click Setup;切换回打包流程前,请使用 Remove Patina From Hosts。

暂存本地 UPM 测试包

如果要测试发布后的包,而不是原始源码检出,请使用此方式:

pwsh -File scripts/stage-local-upm.ps1

然后在 Unity 中从磁盘添加暂存后的包:

  • dist/local-upm/com.taygunsavas.patina-unity-mcp/package.json

验证包布局、导入行为或发布打包时,优先使用暂存的本地包。主动编辑源码并希望实现最快的编辑、构建、运行循环时,优先使用源码检出路径。

完整的贡献者工作流请参阅 CONTRIBUTING.md。

社区与贡献

  • 从 CONTRIBUTING.md 开始,了解本地开发流程、验证要求和拉取请求指南。
  • 使用 GitHub issue 表单提交可复现的错误、功能提议和使用问题,以便维护者获得所需的背景信息。
  • 提交帮助请求前,请阅读 .github/SUPPORT.md。
  • 阅读 .github/SECURITY.md,了解如何私下报告漏洞。
  • 参与 issue 和拉取请求前,请阅读 .github/CODE_OF_CONDUCT.md。
  • 面向 main 的拉取请求应通过 CI,并在启用仓库规则后接受 CODEOWNERS 和 Copilot 审查。

要求

  • Unity 6(6000.3 LTS+)
  • 受支持的 MCP 主机
  • Rust 1.75+(仅限贡献者)

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。