拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Unity MCP get_sha 工具实战:用 SHA256 指纹为 C 脚本变更与并发编辑保驾护航

Unity MCP get_sha 工具实战用 SHA256 指纹为 C# 脚本变更与并发编辑保驾护航【免费下载链接】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本文以 Unity MCP 开源仓库的 get_sha 工具文档 为骨架完整讲解get_sha的调用方式、URI 解析规则、返回值语义并结合 Python 服务端与 Unity Editor 端源码深入剖析它在编辑前并发保护precondition、编辑后变更验证、断连恢复校验等真实场景中的底层工作原理帮助 AI 客户端开发者安全、可靠地自动化 Unity C# 脚本的读写与编辑流程。一、get_sha 是什么只算指纹不吐内容get_sha是 Unity MCP 中core工具组的一员模块位于 Server/src/services/tools/manage_script.py归属于manage_script工具族。它的职责非常明确计算并返回一个 Unity C# 脚本的 SHA256 哈希及其基础元数据但绝不返回文件内容。这一点在官方工具注册描述中被反复强调Get SHA256 and basic metadata for a Unity C# script without returning file contents.参见 get_sha 工具文档 与 manage_script.py 中的注册代码。为什么只算指纹、不吐内容如此重要因为在 MCP 的请求-响应链路中工具返回值最终会以 JSON 形式传输给 AI 客户端。对于大体积脚本文件直接回传全文既浪费 token、拖慢响应也容易触发传输层载荷上限。而 SHA256 作为确定性指纹可以唯一标识文件当前状态——只要内容不变哈希就不变——足以支撑判断文件是否被改动这类核心诉求代价却极小。从工具注解看get_sha被标记为只读readOnlyHintTrue、幂等idempotentHintTrue、非破坏性destructiveHintFalse即多次调用结果一致、不会对 Unity 项目产生任何副作用可以放心地在工作流中高频使用。二、参数与返回值最小化接口设计2.1 参数表get_sha仅接受一个必填参数接口极其精简名称类型必填说明uristr是目标脚本的 URI支持三种形式Assets/下的相对路径、mcpforunity://path/Assets/...协议形式、file://...文件协议形式其中uri参数的官方描述为URI of the script to edit under Assets/ directory, mcpforunity://path/Assets/... or file://... or Assets/...源码注册处。2.2 返回结构get_sha返回标准的 Unity 响应字典核心数据位于data字段经过 Python 服务端裁剪后仅保留两个最小字段manage_script.py L688-L692{ success: true, data: { sha256: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3, lengthBytes: 1234 } }字段类型含义sha256str脚本 UTF-8 文本内容的 SHA256 十六进制小写摘要lengthBytesint脚本按 UTF-8 编码后的字节长度需要注意的是Unity Editor 端返回的原始数据其实更丰富见下文底层实现但 Python 服务端刻意做了裁剪minimal提取只把sha256和lengthBytes透传给客户端。这意味着 Agent 拿到的永远是最精简、最必要的指纹信息。三、URI 解析规则三种写法都能用uri参数之所以支持三种形式是因为 Python 端通过_split_uri函数manage_script.py L19-L68做了统一的归一化解析。理解这个函数就能明白各种 URI 写法的行为差异mcpforunity://path/Assets/...去掉mcpforunity://path/前缀其余部分按Assets相对路径处理。这是 Unity MCP 内部的标准协议写法Unity 端返回的uri字段也使用此格式如mcpforunity://path/Assets/Scripts/A.cs。file://...使用urllib.parse.urlparse拆解对路径做百分号解码unquote对非localhost主机名按 UNC 路径//server/share/...处理随后若路径中存在Assets段则截取该段起作为相对路径。普通路径Assets/...直接使用同样会做解码与分隔符归一化。_split_uri最终把 URI 拆成(name, directory)二元组name是去掉扩展名的文件名directory是相对于Assets的目录部分。解析细节还包括反斜杠统一替换为正斜杠\→/使用os.path.normpath折叠../、./等冗余段Assets段的匹配不区分大小写Windows 盘符路径如/C:/...会剥掉前导斜杠。这解释了为什么文档中强调Requires uri (script path under Assets/ ...)——所有脚本操作都强制限定在Assets/目录内防止越界访问项目外的任意文件。四、底层实现Python 服务端与 Unity Editor 的协作get_sha的实现横跨两层Python 服务端负责参数解析与响应裁剪Unity Editor 端负责真实读取文件并计算哈希。4.1 Unity Editor 端真正的哈希计算者Unity 端实现在 MCPForUnity/Editor/Tools/ManageScript.cs 的get_shaaction 分支L282-L309先检查File.Exists(fullPath)文件不存在则直接返回错误Script not found at {relativePath}.用File.ReadAllText(fullPath)读入文本调用ComputeSha256(text)计算哈希用无 BOM 的UTF8Encoding统计lengthBytes返回包含uri、path、sha256、lengthBytes、lastModifiedUtcISO 8601 格式的 UTC 最后修改时间的完整数据。ComputeSha256的实现ManageScript.cs L856-L864值得留意private static string ComputeSha256(string contents) { using (var sha SHA256.Create()) { var bytes System.Text.Encoding.UTF8.GetBytes(contents); var hash sha.ComputeHash(bytes); return BitConverter.ToString(hash).Replace(-, string.Empty).ToLowerInvariant(); } }它先按UTF-8 字节序列对文件内容编码再计算 SHA256输出 64 位十六进制小写字符串。注意哈希的对象是解码后的文本字符串而非磁盘上的原始字节——因此 BOM、行尾符CRLF/LF等差异会直接影响哈希结果。这保证了 Python 端apply_text_edits使用的precondition_sha256与 Unity 端校验时使用的是同一套口径不会因编码处理差异产生误判。4.2 Python 服务端调用链与响应裁剪Python 端的get_sha函数manage_script.py L672-L695流程为通过get_unity_instance_from_context(ctx)从 MCP 上下文中解析当前目标 Unity 实例支持多实例路由调用_split_uri(uri)得到(name, directory)构造参数{action: get_sha, name: name, path: directory}通过send_with_unity_instanceasync_send_command_with_retry发送给 Unity 端manage_script处理器带重试机制成功后仅保留sha256与lengthBytes两个最小字段返回。这一调用链与集成测试 Server/tests/integration/test_get_sha.py 完全吻合测试用 monkeypatch 替换底层发送函数断言命令名为manage_script、action为get_sha、name提取为A、path以Assets/Scripts结尾并验证返回的data被裁剪为{sha256: ..., lengthBytes: ...}test_get_sha.py L27-L33。该测试是理解参数形状与路由行为的权威参考。五、典型应用场景并发保护、变更验证与断连恢复get_sha单独看只是一个只读指纹工具但它在 Unity MCP 的脚本编辑体系中扮演着枢纽角色主要服务于三个关键场景。5.1 场景一编辑前的并发保护preconditionapply_text_edits工具接受一个可选的precondition_sha256参数manage_script.py L96-L97用途是防止并发编辑AI 客户端在读取脚本并准备编辑时可先用get_sha取得当前指纹再把指纹作为 precondition 随编辑请求一起提交。Unity 端在真正落盘前会做双重校验ManageScript.cs L551-L556string currentSha ComputeSha256(original); if (string.IsNullOrEmpty(preconditionSha256)) return new ErrorResponse(precondition_required, ...); if (!preconditionSha256.Equals(currentSha, StringComparison.OrdinalIgnoreCase)) return new ErrorResponse(stale_file, new { status stale_file, expected_sha256 preconditionSha256, current_sha256 currentSha });未提供 precondition → 返回precondition_required大文件编辑强制要求指纹避免盲目覆盖提供的指纹与当前文件哈希不一致 → 返回stale_file并同时带回expected_sha256与current_sha256客户端可据此判断文件已被其他进程或用户手改、Unity 域重载等改动从而决定是重新get_sha再合并编辑还是放弃本次修改。这正是检查-修改-写入Check-Modify-Write乐观锁范式在 Unity 脚本编辑上的落地get_sha是锁的获取动作precondition_sha256是锁的校验动作。5.2 场景二编辑后的变更验证get_sha还被用于验证编辑是否真的生效。在 Server/src/services/tools/refresh_unity.py 中verify_edit_by_sha函数L138-L165专门负责这件事async def verify_edit_by_sha(unity_instance, name, path, pre_sha): if not pre_sha: return False try: verify await unity_transport.send_with_unity_instance( _legacy_conn.async_send_command_with_retry, unity_instance, manage_script, {action: get_sha, name: name, path: path}, ) ... new_sha (verify.get(data) or {}).get(sha256) return bool(new_sha and new_sha ! pre_sha)其核心思想编辑前记录旧哈希编辑后再调get_sha取新哈希二者不同即说明文件确实被改写。apply_text_edits在断连后通过_verify_edit回调复用此逻辑manage_script.py L329-L332返回Edit applied (verified after domain reload).。5.3 场景三Unity 域重载 / 连接中断后的恢复校验脚本编辑通常会触发 Unity 编译与域重载domain reload期间 MCP 连接可能短暂中断导致编辑请求发出后无法立即确认结果。send_mutation封装了完整的恢复模式refresh_unity.py L92-L135以retry_on_reloadFalse发送变更避免重载时重复执行若收到重载拒绝 → 等待编辑器就绪后重试一次若发送后连接丢失 → 等待编辑器就绪通过verify_after_disconnect回调内部即verify_edit_by_sha→get_sha确认变更是否已落盘最终等待编辑器就绪后再返回。get_sha在这里成为连接断开后判定编辑成败的唯一依据是保证脚本编辑工作流在域重载场景下可靠性的关键一环。此外结构化编辑工具script_apply_edits在部分操作中同样依赖get_sha动作见 script_apply_edits.py L958而manage_script_capabilities也会在extras中声明get_sha: Truemanage_script.py L649表明该能力对客户端是公开且可查询的。六、实战调用示例由于get_sha是 MCP 工具实际调用由 AI 客户端通过 MCP 协议完成。以下展示三种uri写法的等价调用语义返回结构均相同// 写法一Assets 相对路径 { uri: Assets/Scripts/PlayerController.cs } // 写法二mcpforunity 协议形式 { uri: mcpforunity://path/Assets/Scripts/PlayerController.cs } // 写法三file 协议形式 { uri: file:///path/to/project/Assets/Scripts/PlayerController.cs }预期返回{ success: true, message: SHA computed for Assets/Scripts/PlayerController.cs., data: { sha256: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3, lengthBytes: 2048 } }一个推荐的安全编辑组合工作流如下调用get_sha获取目标脚本当前指纹sha_before可选先resources/read或find_in_file确认目标行的精确内容调用apply_text_edits在precondition_sha256字段填入sha_before若返回stale_file说明文件在编辑前已被改动重新执行步骤 1基于最新指纹合并修改后重试编辑完成后再次get_sha若sha256 ! sha_before则确认变更已生效。七、小结与最佳实践get_sha以极小的接口面积一个参数、两个返回值承载了 Unity MCP 脚本编辑体系中最关键的一致性保障职责。使用时的最佳实践总结如下编辑前必取指纹对大文件或多人/多 Agent 协作场景任何写入类操作前都应先get_sha并将指纹作为precondition_sha256提交以获取stale_file保护指纹即变更信号利用哈希变化 文件被改写这一特性在域重载或断连后验证编辑是否真正落盘区分编码口径哈希基于 UTF-8 解码后的文本计算BOM 与行尾符变化会导致哈希变化不要误判为内容被实质修改只读、幂等、可高频调用get_sha对 Unity 项目无任何副作用可放心在循环、批量场景中反复使用URI 越界防护所有脚本路径都被限定在Assets/下若收到path_outside_assets类错误请检查uri是否指向了项目目录之外。如需继续深入可进一步阅读get_sha 工具文档、Python 服务端实现、Unity 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创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门