Unity MCP manage_editor 工具完全指南:编辑器状态控制、标签/图层管理与包部署实战
2026/9/14 14:21:12 网站建设 项目流程

Unity MCP manage_editor 工具完全指南:编辑器状态控制、标签/图层管理与包部署实战

【免费下载链接】unity-mcpUnity MCP acts as a bridge between AI assistants and your Unity Editor. Give your LLM tools to manage assets, control scenes, edit scripts, and automate tasks within Unity.项目地址: https://gitcode.com/GitHub_Trending/un/unity-mcp

导读

manage_editor是 Unity MCP(MCP for Unity)核心工具组(core)中负责控制与查询 Unity 编辑器状态和设置的桥接工具,由 Python 服务端与 Unity 编辑器端共同实现。通过它,LLM 可以一键进入/退出播放模式、切换场景工具、增删 Tag 与 Layer、触发 MCPForUnity 包部署/回滚,以及执行 Undo/Redo,从而把“操作编辑器本身”纳入自动化工作流。读完本文你将掌握manage_editor的全部 14 个 action 的参数与返回值、底层调用链、以及如何与只读资源配合实现完整的编辑器自动化。


一、工具定位与 action 总览

根据 manage_editor 参考文档,该工具属于core组,模块名为services.tools.manage_editor。它同时提供只读修改型两类 action:

  • 只读(Read-only)telemetry_statustelemetry_ping
  • 修改(Modifying)playpausestopset_active_tooladd_tagremove_tagadd_layerremove_layerdeploy_packagerestore_packageundoredo

注意:Prefab 编辑(打开/保存/关闭 Prefab Stage)不属于本工具职责,应使用manage_prefabs

参数表

NameTypeRequiredDescription
actionLiteral['telemetry_status', 'telemetry_ping', 'play', 'pause', 'stop', 'set_active_tool', 'add_tag', 'remove_tag', 'add_layer', 'remove_layer', 'deploy_package', 'restore_package', 'undo', 'redo']yes获取和更新 Unity 编辑器状态。deploy_package将配置的 MCPForUnity 源码复制到项目包目录(会触发重编译);restore_package从备份恢复最近一次部署;undo/redo执行编辑器撤销/重做。Prefab 编辑请使用manage_prefabs
tool_namestr \| None设置活动工具时使用的工具名
tag_namestr \| None添加/删除标签时的标签名
layer_namestr \| None添加/删除图层时的图层名

返回值

返回一个包含 Unity 响应的dict,具体形状随 action 不同而变化。通用成功形态为{"success": true, "message": "...", "data": ...},失败时为{"success": false, "message": "..."}(详见下文源码解析)。


二、播放模式控制:play / pause / stop

三个 action 分别对应进入、暂停/恢复、退出播放模式,是自动化验证场景行为的最常用入口:

manage_editor(action="play") # 进入 Play Mode manage_editor(action="pause") # 暂停(再次调用则恢复) manage_editor(action="stop") # 退出 Play Mode

Unity 端的实现位于 ManageEditor.cs,核心逻辑围绕EditorApplication.isPlayingEditorApplication.isPaused

  • play:若!EditorApplication.isPlaying则置为true并返回"Entered play mode.";已在播放模式则幂等地返回"Already in play mode."
  • pause:仅在播放模式下生效,将isPaused取反,返回"Game paused.""Game resumed.";非播放模式返回错误"Cannot pause/resume: Not in play mode."
  • stop:播放中则退出并返回"Exited play mode.";否则返回"Already stopped (not in play mode)."

从 manage_editor.py 可以看到,Python 服务端只负责参数组装与转发,真正执行动作的是 Unity 编辑器进程。


三、切换活动工具:set_active_tool

set_active_tool用于切换 Unity 场景视图的当前工具,等价于点击工具栏的 View/Move/Rotate/Scale 等按钮:

manage_editor(action="set_active_tool", tool_name="Move") # View | Move | Rotate | Scale | Rect | Transform

在 ManageEditor.cs 中,tool_name会通过Enum.TryParse<Tool>(toolName, true, ...)大小写不敏感地解析为 Unity 内置Tool枚举。合法取值包括ViewMoveRotateScaleRectTransform;解析成功后通过UnityEditor.Tools.current = targetTool生效。需要注意两点边界:

  • 若解析出的值属于Tool.NoneTool.Custom或超出标准枚举范围,会返回错误"Cannot directly set tool to ...",因为这两者无法直接通过Tools.current切换;
  • 解析失败时提示可用的标准工具列表(View, Move, Rotate, Scale, Rect, Transform, Custom)。

四、标签管理:add_tag / remove_tag

用于向项目TagManager.asset添加或移除标签:

manage_editor(action="add_tag", tag_name="Enemy") manage_editor(action="remove_tag", tag_name="OldTag")

Unity 端实现细节(ManageEditor.cs):

  • add_tag:先通过InternalEditorUtility.tags检查标签是否已存在(存在则报错),再调用InternalEditorUtility.AddTag(tagName),随后AssetDatabase.SaveAssets()强制持久化到磁盘。
  • remove_tag:拒绝移除内置的Untagged标签(Cannot remove the built-in 'Untagged' tag.);标签不存在时报Tag '...' does not exist.;移除成功后同样执行SaveAssets()
  • 空字符串或纯空白名称一律被拒绝。

配合只读资源使用:在调用前,可以通过mcpforunity://get_tags资源(实现见 Tags.cs)读取当前全部标签,避免重复添加或删除不存在的标签。


五、图层管理:add_layer / remove_layer

用于向ProjectSettings/TagManager.asset的 layers 数组添加或移除用户图层

manage_editor(action="add_layer", layer_name="Projectiles") manage_editor(action="remove_layer", layer_name="OldLayer")

Unity 端实现(ManageEditor.cs)通过SerializedObject直接操作ProjectSettings/TagManager.assetlayers属性,其关键约束体现了 Unity 图层机制本身:

  • 用户图层区间:仅使用索引 8~31(FirstUserLayerIndex = 8TotalLayerCount = 32),前 8 层是 Unity 内置层,不可由用户修改。
  • add_layer:先做全数组大小写不敏感的重名检查(重复则返回已存在的索引),再查找第一个空的用户图层槽位;若 8~31 全部被占用,返回"No empty User Layer slots available (8-31 are full)."。写入后调用ApplyModifiedProperties()AssetDatabase.SaveAssets()
  • remove_layer:仅在用户图层区间内按名称(忽略大小写)查找;找不到返回"User layer '...' not found.";找到后将对应槽位字符串置空实现“删除”。
  • 图层名称同样不允许为空或纯空白。

六、包部署与回滚:deploy_package / restore_package

这是本工具中风险最高也最实用的能力,专门服务于“LLM 驱动迭代”场景:将配置好的 MCPForUnity 源码目录复制到当前项目已安装的包目录中,立即触发重编译且无确认弹窗

manage_editor(action="deploy_package") # 复制源码到已安装包位置并触发 AssetDatabase.Refresh manage_editor(action="restore_package") # 从上次部署的备份中恢复

底层调用链

  • Unity 端入口在 ManageEditor.cs,分别调用MCPServiceLocator.Deployment.DeployFromStoredSource()RestoreLastBackup(),返回结果中携带source_pathtarget_pathbackup_path

  • 真正实现位于 PackageDeploymentService.cs:

    • 源码路径来源:存储在EditorPrefsPackageDeploySourcePath键中(对应 EditorPrefKeys.cs),需先在 MCP for Unity 的 Advanced Settings 中设置。未设置时DeployFromStoredSource()返回"Select a MCPForUnity folder first."
    • 源码校验:目录必须同时包含EditorRuntime两个子文件夹,否则拒绝部署。
    • 目标路径解析:优先使用PackageInfo.FindForAssembly(...)获取已安装包的resolvedPath/assetPath,失败则回退到AssetPathUtility.GetMcpPackageRootPath()计算的包根目录。
    • 部署过程:先在Library/MCPForUnityDeployBackups/backup_<时间戳>创建目标目录的完整备份,再用FileUtil.DeleteFileOrDirectory+CopyFileOrDirectory覆盖目标的EditorRuntime两个核心文件夹,最后AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate)触发重编译。
    • 回滚:从EditorPrefs读取最近一次备份与目标路径,将备份目录整体覆盖回目标路径并再次Refresh

部署工作流建议

按 tools-reference.md 中的说明,完整的自动化部署链路应为:

  1. 在编辑器 Advanced Settings 中设置 MCPForUnity 源码文件夹路径;
  2. manage_editor(action="deploy_package")完成复制 + 备份 +Refresh
  3. 由于部署会触发脚本重编译,随后调用refresh_unity(mode="if_dirty", wait_for_ready=True)等待编辑器重新编译完成,再进行后续操作。

七、撤销与重做:undo / redo

undo/redo直接调用 Unity 的 Undo 系统并返回受影响的撤销组名称,便于 LLM 感知操作上下文:

manage_editor(action="undo") manage_editor(action="redo")

Unity 端实现(ManageEditor.cs):

  • undo:先通过Undo.GetCurrentGroupName()取得当前撤销组名,执行Undo.PerformUndo();若组名为空则提示"Undo performed (stack may be empty)."。返回数据包含undone_group(被撤销的组名)与next_group(撤销后的当前组名)。
  • redo:执行Undo.PerformRedo(),返回current_group
  • 播放模式警告:在播放模式下执行 undo/redo 时,返回消息会附加"Warning: undo during play mode may have unexpected effects.",提醒调用方该操作在播放模式下的行为可能与预期不符。

八、只读遥测:telemetry_status / telemetry_ping

这两个 action 是唯二由 Python 服务端直接处理、不转发到 Unity的动作,属于诊断类接口:

manage_editor(action="telemetry_status") # 返回: {"success": true, "telemetry_enabled": true|false} manage_editor(action="telemetry_ping") # 返回: {"success": true, "message": "telemetry ping queued"}
  • telemetry_status直接调用 telemetry.py 中的is_telemetry_enabled(),读取服务端遥测开关状态。
  • telemetry_ping通过record_tool_usage("diagnostic_ping", True, 1.0, None)向遥测队列写入一条工具使用记录(异步、非阻塞),用于验证遥测链路是否可用。

从 test_manage_editor.py 的测试用例可以确认:这两个 action 由 Python 端就地处理,不会出现在转发给 Unity 的参数中(assert "params" not in mock_unity)。


九、服务端转发机制与参数裁剪

所有需要 Unity 执行的 action 都遵循统一的转发流程,其源码在 manage_editor.py:

  1. 通过get_unity_instance_from_context(ctx)从请求上下文中获取当前活动的 Unity 实例(由中间件注入,支持多实例路由);
  2. 组装{action, toolName, tagName, layerName}参数字典,并剔除所有值为None的键——测试 test_undo_omits_none_params 专门验证了这一点;
  3. 调用send_with_unity_instance(async_send_command_with_retry, unity_instance, "manage_editor", params),经由统一的重试辅助函数发送命令;
  4. 对响应做统一包装:成功时展开为{"success": true, "message": ..., "data": ...};失败时原样返回结构化错误;任何异常兜底为{"success": false, "message": "Python error managing editor: ..."}

UNITY_FORWARDED_ACTIONS参数化测试(test_manage_editor.py)逐一验证了playpausestopset_active_tooladd_tagremove_tagadd_layerremove_layerdeploy_packagerestore_packageundoredo这 12 个动作都会以manage_editor工具名正确转发到 Unity。

另外,该工具在注册时通过ToolAnnotations标注了readOnlyHint=FalsedestructiveHint=True(见 manage_editor.py),向 MCP 客户端明确提示它属于破坏性/修改型工具,调用时应谨慎。


十、与只读资源的分工:何时用工具,何时用资源

manage_editor负责写操作,而读取编辑器状态应优先使用 MCP 资源,二者形成清晰分工:

需求推荐方式仓库依据
进入/退出/暂停播放模式manage_editor(action="play"/"stop"/"pause")ManageEditor.cs
切换场景工具manage_editor(action="set_active_tool", tool_name="Move")ManageEditor.cs
增删 Tagmanage_editor(action="add_tag"/"remove_tag")ManageEditor.cs
增删 Layermanage_editor(action="add_layer"/"remove_layer")ManageEditor.cs
部署/回滚包manage_editor(action="deploy_package"/"restore_package")PackageDeploymentService.cs
撤销/重做manage_editor(action="undo"/"redo")ManageEditor.cs
查询当前 Tag 列表资源mcpforunity://get_tagsTags.cs
查询编辑器动态状态(含活动工具、播放状态等)资源mcpforunity://get_editor_stateEditorState.cs、EditorStateCache.cs

当 action 参数非法或缺失时,Unity 端会返回包含全部受支持 action 列表的错误信息,并在其中提示“Use MCP resources for reading editor state, project info, tags, layers, selection, windows, prefab stage, and active tool.”(见 ManageEditor.cs),即读取类操作请走资源通道。


十一、使用注意事项与最佳实践

  1. deploy_package 会触发重编译且无确认弹窗:部署会覆盖已安装包的Editor/Runtime目录并立即刷新资源库。执行前请确认 Advanced Settings 中的源码路径指向正确的 MCPForUnity 目录,且目标与源目录不同(服务端会拒绝“源等于目标”的情况)。
  2. 部署后务必等待重编译完成:建议紧跟refresh_unity(wait_for_ready=True),避免在编译中继续下发依赖新代码的命令。
  3. 备份即保险:每次deploy_package都会在Library/MCPForUnityDeployBackups/下生成带时间戳的完整备份,restore_package依赖该备份路径(存储在EditorPrefs中)。若无备份可用,回滚会返回"No backup available to restore."
  4. 修改前先查询:增删 Tag/Layer 前先读get_tags或查看 TagManager 当前内容;图层仅能操作索引 8~31 的用户层,删除内置层会失败。
  5. 播放模式下谨慎 undo/redo:工具会主动附加警告,建议在编辑模式下执行撤销/重做。
  6. 参数大小写不敏感但校验严格tool_name解析忽略大小写;Tag/Layer 名称不允许空串,重复添加与删除不存在对象都会返回明确错误信息,LLM 可直接依据 message 字段进行纠偏。

小结

manage_editor将 Unity 编辑器“自身”变为可编程对象:播放控制、工具切换、Tag/Layer 维护、包部署回滚与撤销重做共 14 个 action,配合mcpforunity://get_editor_stateget_tags等只读资源,足以支撑“LLM 全自动驱动编辑器状态流转”的复杂工作流。其架构上采取 Python 服务端参数裁剪 + 实例路由、Unity 端EditorApplication/InternalEditorUtility/SerializedObject落地执行的清晰分层(详见 manage_editor.py 与 ManageEditor.cs),并有 test_manage_editor.py 对转发行为与参数裁剪做了完整回归保障。需要编辑 Prefab 时请转向manage_prefabs工具,完整的工具体系参考可见 tools-reference.md。

【免费下载链接】unity-mcpUnity MCP acts as a bridge between AI assistants and your Unity Editor. Give your LLM tools to manage assets, control scenes, edit scripts, and automate tasks within Unity.项目地址: https://gitcode.com/GitHub_Trending/un/unity-mcp

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询