【免费下载链接】unreal-engine-skills-for-claude-code-plugin
本文围绕开源项目unreal-engine-skills-for-claude-code-plugin讲解如何为 Unreal 编写 AI 可调用的工具集(Toolset)。这个项目让 Claude Code 通过 MCP 协议直接操控正在运行的 Unreal Editor——从生成 Actor、编辑蓝图到修改材质,覆盖 30+ 个工具集、数百个工具。本文将完整走读其create-toolset技能文件,带你从零学会设计和注册一个属于自己项目的工具集。🎮
先搞清楚:什么是 Toolset?
在动手之前,先理解整个体系如何运转:
- Toolset是一组静态的、可被 AI 调用的函数,注册到引擎的
ToolsetRegistry中,再通过 MCP 服务器暴露给 Claude Code; - 由于默认开启了工具搜索(Tool search),MCP 服务器只发布 3 个"元工具":
list_toolsets、describe_toolset、call_tool。AI 不需要记住几百个工具名,而是按需发现工具集,读取参数结构后同轮派发调用——上下文窗口小、提示缓存保持温热; - 换句话说:你写的每一个工具方法,最终都会变成 Claude 在编辑器里能"动手"的一个动作。
这套发现与调用的契约定义在 skills/unreal-mcp/SKILL.md 中,而本文的主角 skills/create-toolset/SKILL.md 则是编写工具集的完整规范。
开发前提:3 个快速检查项
在编写工具集之前,确认你的环境已就绪(详见 skills/unreal-mcp/references/setup.md):
- 项目中已启用
ModelContextProtocol与AllToolsets两个插件——只开前者服务器能启动但不暴露任何工具; - 编辑器已启动 MCP 服务器(编辑器控制台执行
ModelContextProtocol.StartServer,默认端口8000,路径/mcp); - 若打算用 Python 写工具集,需在Edit → Project Settings → Plugins → Python中开启Developer Mode并重启编辑器,以便生成 Python stubs 供 API 查询。
动手前的 5 个关键问题
create-toolset规范强调:写任何代码之前,先按顺序回答这 5 个问题,能避免 80% 的返工。
1. 这个功能是不是已经存在?
编辑器在运行时,先通过 MCP 调用list_toolsets查看已注册的工具集,再对相关的调用describe_toolset查看其工具列表;MCP 不可用时,直接搜索代码库中名为Toolsets的文件夹。如果能力已被暴露,就没有新工具要做——把用户指向现有工具即可。
2. 需求是否比表面更通用?
用户常以领域内需求的形式提出一个更普遍的模式。比如"读取蓝图资产元数据"看似属于BlueprintTools,但元数据对所有资产都适用,正确归属是AssetTools。通用解法几乎总是优于狭窄解法。
3. 该领域是否已有工具集?
若功能确实缺失、但已有工具集覆盖同一领域(比如给StaticMeshTools加一个网格查询),往现有工具集里加,而不是新建一个。
4. 新工具集需要独立插件吗?
与现有插件关系紧密就加进去;领域足够独立才考虑单独建插件。拿不准时,先问用户。
5. 选 Python 还是 C++?
- Python 通常优先:迭代快、易修改。判断依据是 Python stubs 文件
<project_root>/Intermediate/PythonStub/unreal.py(搜索它,别整体通读)中是否覆盖了所需 API; - C++是 Python 覆盖不足时的正确选择,大多数引擎底层能力并不在 stubs 里;
- 如果两种语言的 API 都缺失,不要绕路——停下来告诉用户去扩展引擎,绕路只会造出静默崩溃的脆弱工具。
设计原则:好工具集的 4 个特征
规范给出了一组精炼的启发式标准,值得贴在屏幕边:
| 原则 | 含义 |
|---|---|
| Clean(简洁) | 设计能完成领域工作的最简 API,不要直接照搬 Unreal 原生 API(往往过于复杂)。自检:技术美术不看实现能看懂吗? |
| Complete(完整) | 保持 CRUD 对称:能 set 就该能 get,有 create 就该有 delete |
| Composable(可组合) | 同类操作在各工具间使用一致的类型:get_graph()返回Graph,那get_graph_nodes()就应接收Graph |
| DRY(无重复) | 工具集内部不重复,工具集之间也不重复。ObjectTools已提供通用 UObject 属性读写,别再实现一份 |
跨语言通用约定
以下约定对 C++ 和 Python 工具集同样生效,是"能上线"的底线:
- 不重复造轮子:已有工具提供的能力直接调用或指向它;
- 文档是强制项:每个工具集、每个工具方法、每个结构体字段都必须有文档(下一节细讲);
- 使用真实类型:参数和返回值用真实类型(
int32、FVector、TArray<FString>、结构体等),序列化由 ToolsetRegistry 自动处理。在工具内部手动转 JSON 字符串是典型的代码坏味道——字符串类型就应真的表示字符串; - 返回值携带数据而非状态:正常返回即成功,抛异常即失败。永远不要用布尔值、错误字符串或结果包装体来传达错误;
- 所有工具方法都是静态的:无实例状态;
- 测试是强制项:每个工具的成功路径和每个错误路径都要覆盖。
文档怎么写:让每句话都"赚回位置"
这是规范中最有见地的部分之一,核心检验标准是一句话:
一个有能力的读者能否仅凭函数签名、命名和类型推断出这句文档?如果能,删掉它。
具体到三个层级:
- 工具集类:写 1~3 句话说明这个工具集做什么、覆盖什么领域。因为 LLM 经常只看名字和这段描述、而从不加载具体工具,它必须独立成立。不要罗列工具名——工具自己会说话;
- 每个工具:写清它做什么,文档化每个参数与返回值,重点是语义和单位;
- 保留那些无法推断的信息:单位、取值范围、不直观的编码方式(例如"单个空格分隔的字符串")、空结果的含义;
- 删掉这些内容:签名复述(类型、默认值、可空性)、工具如何串联的叙述、显而易见的使用示例、对字段内容的猜测。另外,写代码"做什么"而不是"为什么这样写"——实现理由不是契约。
一个典型的"过度文档 vs 精简后"对比见 skills/create-toolset/SKILL.md 中的run cheat示例。结构体方面,ClampMin/ClampMax等 UPROPERTY 元数据会被自动提取进 schema,无需在文档注释里重复约束。
Python 路线:最快上手路径
Python 工具集的结构要求(完整示例代码见 skills/create-toolset/SKILL.md):
- 类用
@unreal.uclass()装饰,继承unreal.ToolsetDefinition,一个 .py 文件一个工具集类; - 每个 AI 可调用的工具用
@toolset_registry.tool_call+@staticmethod双装饰器,docstring 就是 AI 看到的工具描述; - 每个参数和返回值必须有类型注解——schema 生成完全依赖它们,且优先使用标准 Python 注解(
list[str]而非unreal.Array[str]),装饰器会自动转换; - 私有辅助方法用下划线前缀的
@staticmethod,放在类末尾; - 注册从不自动发生:在插件的
__init__.py或init_unreal.py中调用unreal.ToolsetRegistry.register_toolset_class(MyToolset),与其他工具集并列; - 错误处理直接抛异常(如
ValueError),不要返回错误字符串。
编辑后编辑器不会自动感知变化:开启 Remote Execution 后运行reload_remote.py your_plugin重新加载插件包即可。
C++ 路线:核心要点
C++ 工具集的骨架与 Python 一一对应,要点如下:
- 继承
UToolsetDefinition,一个.h/.cpp文件一个工具集类; - 可调用工具是静态方法并标注
UFUNCTION(meta = (AICallable)),函数文档注释即 AI 可见描述;私有辅助方法省略该宏即不暴露; - 注册:常见模式是在模块
StartupModule/ShutdownModule中调用UToolsetRegistry::RegisterToolsetClass/UnregisterToolsetClass,先查看同插件内邻近工具集的既有写法; - 异步工具:截图、等待编辑器状态变化等长时操作返回
UToolCallAsyncResult的子类,成功调SetValue()、失败调SetError()——这是少数"成功失败都走结果对象"的场景,先查已有的结果类型再考虑新建; - 错误处理:无法完成工作时用
UKismetSystemLibrary::RaiseScriptError抛出脚本错误并立即返回空值/默认值; - 自定义 JSON 转换器属于进阶能力,仅在确有需求时再写
FToolsetJsonConverter子类,参考内置的FToolsetColorConverter、FToolsetTransformConverter等实现。
测试:两种验证方式
方式一:活编辑器(推荐)
通过unreal-mcp连接运行中的编辑器是最快的迭代回路——改完可热编译/热加载,结果即时返回,C++ 与 Python 测试都适用:
- 加载
AutomationTestToolset并调用DiscoverTests——这一步必须先做,跳过会导致结果为空; ListTests按工具集名过滤,确认测试被发现;RunTests传入完整测试路径;- 轮询
GetTestStatus,再用GetTestResults查看每个测试的错误与警告。
Python 测试重载后记得用force_rediscover=true重新发现。
方式二:命令行(无运行中的编辑器)
命令行会拉起一个无头编辑器实例(启动约 30 秒),适合 CI 场景,大致形如UnrealEditor-Cmd.exe <项目>.uproject -ExecCmds="Automation RunTests AI.MyToolset;quit" -Unattended -NullRHI,具体标志请以同插件现有测试的跑法为准。C++ 侧跑测试前先用LiveCodingToolset.CompileLiveCoding编译(它会阻塞到编译完成并暴露 MSVC 诊断)。
交付前:自查清单
代码写完、测试通过后,规范要求你退后一步整体审读一遍——第一轮代码常有逐工具视角发现不了的问题:
- 重复样板:跨工具可共享的辅助逻辑;
- 测试覆盖不全:晚加的错误分支忘了补测试;
- 功能重复:与同工具集或别处工具撞车;
- API 不一致:参数命名、类型与工具集内其他工具不统一;
- 文档缺失:描述含糊、类 docstring 独立来看信息不足;
- 文档复述代码(更常见的毛病):重复类型、默认值、调用序列的行,读一遍注释,把任何"能从签名推断"的句子砍掉。
发现就修,干净的第二轮比事后的 bug 报告快得多。✅
写在最后
这个项目的分工非常清晰:unreal-mcp技能教 AI调用工具(skills/unreal-mcp/ 还附带 setup.md 与 operations.md 两份运维参考),create-toolset技能教人编写工具,unreal-skill(skills/unreal-skill/SKILL.md)则负责项目级 Agent Skill 的编写。配套的 SessionStart 钩子(hooks/hooks.json 与 hooks/unreal-context.sh)会在每次会话开始时自动注入 UE 项目上下文。
掌握本文的 5 个前置问题、4 条设计原则与 6 条通用约定后,你就可以为自己的项目写出让 AI 真正"上手干活"的工具集了。更多背景信息见项目说明 README.md。
【免费下载链接】unreal-engine-skills-for-claude-code-plugin
相关推荐
Claude Skills生态重构:从文本生成到企业级工作流自动化的技术革命
Claude Skills生态重构:从文本生成到企业级工作流自动化的技术革命 在AI助手能力边界不断扩展的今天,Claude Skills生态系统正经历着从简单
AI 技能AI 插件人工智能终极指南:PySide6 QDateTimeEdit日期时间控件的5个高效使用技巧
终极指南:PySide6 QDateTimeEdit日期时间控件的5个高效使用技巧 你是否曾经在开发PySide6 GUI应用时,为日期时间输入而烦恼?用户需要
示例工程教程桌面应用open-reverselab MCP 工具清单:完整指南,100+ 个 AI 可调用的逆向工具如何选、如何用
open reverselab MCP 工具清单:完整指南,100+ 个 AI 可调用的逆向工具如何选、如何用 open reverselab 是一个开源的 A
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考