关于 unity-cli
通过 `cs` 命令行使用已记录的命令路由、代码片段和 C# 执行来操作 Unity 项目。该技能强调按范围发现命令、通过文件传入参数,并谨慎处理项目变更。
主要功能
- 01按内置命令和自定义命令路由任务
- 02按领域和层级发现命令
- 03通过文件传入 C# 和 JSON
- 04支持隔离且可复用的 REPL 会话
- 05写入设置前要求用户批准
适用场景
- 01查找所需 Unity 操作对应的命令
- 02执行 C# 检查或项目操作
- 03批量运行结构化 Unity 命令
- 04管理相关执行间的会话状态
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ niqibiao/ unity-cli-skill --skill unity-cli安装后在 Claude Code 中输入/unity-cli确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/catalog.mdcommands.mdexec-code.mdlogs.mdplayer.mdrefresh.mdsetup.mdsnippets-audit.mdsnippets.mdstatus.mdtests.mdscripts/cli/__init__.py__main__.pycatalog_store.pycommand_discovery.pycommand_preflight.pycore_bridge.pycs.pypaths.pyregistry_cache.pyregistry_protocol.pyregistry_resolver.pyreliability.pyrouting_overlay.jsonVERSIONscripts/cli/snippets/__init__.pyrender.pystats.pystore.pyvalidate.py详细介绍
Unity CLI
一个 CLI(cs)可驱动 Unity Editor/Player。默认的创作操作界面划分为六个面向 Agent 的领域,因此只有相关架构才会进入上下文;控制面和项目自定义命令使用显式视图。
cs list-commands 是一项控制面 CLI 发现操作,并非规范包契约 command/list。它的 CLI 标志永远不是 command/list 参数,发现调用也不得表示为规范命令路由。
仅当用户明确要求该包契约时,才使用 command/list。
发现操作返回的记录带有创作、自定义或控制面层级。
运行 cs
下文中的 cs 指:
python "<SKILL_DIR>/scripts/cli/cs.py"
<SKILL_DIR> 是加载此技能时提供的技能绝对基础目录。每次调用时,都将 cs 展开为该绝对命令,并在不更改当前目录的情况下运行。
不要枚举其他技能安装,也不要运行 cs --help 来重新发现本文档所述的操作界面;本文档及其返回的 Route Cards 已涵盖路由所需的全部信息。
正常使用时不要传入 --project。CLI 会从工作目录和自身已提交的位置分别向上查找 Unity 项目。--project <path> 仅用于有意指定其他项目。
CLI 会就地运行;没有引导或复制步骤。cs setup 是一种便捷方式,而非必经步骤。如果软件包不存在或使用了 --update,setup 会写入共享的 Packages/manifest.json。在任何会产生写入的 setup 操作之前,说明它将添加的确切来源并征得用户批准。参见 references/setup.md。
传递输入
绝不要通过 shell 内联传递 C# 代码或结构化命令参数。先写入文件,再传入其绝对路径:
exec的原始 C# 代码通过--file写入.cs文件。command和batch的结构化参数通过--input写入 JSON 文件。
必须使用的临时目录是:
<project-root>/Temp/CSharpConsole/AgentScratch/
此目录位于 Unity 管理的 Temp/ 中,不会被导入,通常也会被 git 忽略。务必使用完整绝对路径。文件名应体现任务含义,按顺序修改时覆盖同一文件;只有在确认另一个 Agent 正同时操作同一 Unity 项目时,才使用随机后缀。
临时载荷仅供一次性使用。可复用的 C# 代码应放入代码片段库。只清理 AgentScratch/;绝不要删除包含服务状态的 Temp/CSharpConsole/。绝不要将 REPL 载荷写入 Assets/:导入这些文件可能导致项目无法编译,并阻止服务重启。
cs exec --file "<project-root>/Temp/CSharpConsole/AgentScratch/inspect-camera.cs"
cs command --json --input "<project-root>/Temp/CSharpConsole/AgentScratch/req-create-cube.json"
cs batch --json --input "<project-root>/Temp/CSharpConsole/AgentScratch/req-batch.json"
REPL 会话
默认情况下,cs exec 会启动一个新会话。对于自包含代码,请保留此默认设置。如果后续提交会有意依赖此前创建的变量、using、类型或辅助程序,请生成一个不透明的任务专用 ID 并重复使用:
cs exec --session agent-a1b2c3 --file "<project-root>/Temp/CSharpConsole/AgentScratch/inspect-camera.cs"
cs exec --session agent-a1b2c3 --file "<project-root>/Temp/CSharpConsole/AgentScratch/use-camera.cs"
绝不要在无关任务或 Agent 之间共享会话。域重新加载会清除会话状态,因此在运行 cs refresh 后,请重建上下文或使用新 ID。有关生命周期和重置详情,请参见 references/exec-code.md。
路由
每项任务都遵循以下规范顺序:内置命令 → 项目自定义命令 → 代码片段 → 原始 exec。不要为了使用 C# 而跳过匹配的内置命令。 软件包注册表是可执行契约的权威来源;已提交的自定义目录仅是共享的候选列表。
对于结构化 Unity 操作,应在加载执行详情之前完成发现:
常规内置编写发现预算为:每个非空层级调用一次 Route Card,然后总共调用一次精确 ID。只有在流程结束后确实出现新需求,才允许进行一次范围明确的内置查询,并记录原因。
维护一份发现台账。台账的范围限定为当前 Agent 会话和已解析的项目目标。其键包括选择器类型(domain 或 id)、规范化视图、层级、排序后的选择器、解析模式(live、offline 或显式 refresh),以及投影/详情模式(compact 或 verbose)。启动前将签名标记为进行中,成功后标记为已完成;对于已完成或进行中的签名,必须复用或等待。绝不能用离线条目满足必需的实时比较。只有在项目、台账代次和详情模式均相同,且满足 cacheStored:true 时,存储的实时或刷新条目才可满足其他条件完全相同的离线请求;其他任何跨模式或跨详情复用均无效。台账是 Agent 内存中的记录;不要查询实时时间,也不要创建台账文件。
刷新是独占屏障:等待该项目所有进行中的查询结束,然后单独启动刷新。只有 source:"live" 且 cacheStored:true 的刷新结果才会创建新的台账代次;将该刷新记录为新代次的首个条目,并使较早的已完成条目失效。过期缓存或回退刷新绝不会推进代次,也不能满足后续离线查询;对于较早台账代次的任何迟到结果,都应丢弃,不得记录或使用。
实时或刷新查询超时,或终止状态未知时,不要重试;停止并报告其状态不确定。只有在确认退出码非零且没有结果时,才可将离线查询重试一次,沿用同一台账条目并记录原因。成功的查询绝不重新发送。
- 调用前收敛领域范围。 根据每项请求的修改、前置条件、明确不变量、独立验证和回退检查,构建完整的 Core 和 Advanced 领域集合。下表是常规领域索引;跳过未筛选的索引调用。仅 Advanced 列表是有条件的,并非检查清单:直接编辑
prefab/asset_*、prefab/unpack、创建资源文件夹和捕获 Scene View 都属于 Advanced。prefab/create和prefab/instantiate仍属于prefabs/core;通用 Prefab 枚举仍属于assets/core。同一领域可以同时属于两个层级。文件夹加材质的工作流会使assets同时进入两个集合:创建文件夹属于 Advanced,而创建、检查和指定材质属于 Core。绝不能让 Advanced 意图取代该领域中另一项请求的 Core 操作。存在 Prefab 领域意图时,仅当所有意图都是直接的prefab/asset_*操作或prefab/unpack,才省略prefabs/core。 每项领域/层级选择都必须对应一项明确请求的操作;排除项、示例和并行性绝不会扩大查询集合。明确指定的读取或验证会决定其层级,而修改后的通用回读不会,因为精确契约已提供其直接关联。可能发生的后续深入检查绝不会扩大初始领域集合;等上游读取表明有此必要后再进行。唯一可能用途是这种延后深入检查的领域为空,必须省略。例如,全面扫描场景层级不会仅因返回的某个对象之后可能需要检查,就选择objects;扫描/报告意图是层级读取,并不隐含逐对象或逐组件读取。扫描所有 Prefab 资源层级时,枚举属于assets/core,层级检查属于prefabs/advanced;省略prefabs/core。 - 执行 Route Card 轮次。 每个非空层级恰好使用一次多领域查询。精简结果会保留
cacheStored,因为它用于保障缓存生成连续性。首次实时调用会执行本会话唯一一次指纹比对。当实时工作流的两个层级都非空时,Core 必须是首次实时调用;只有 Core 为空时,Advanced 才可以先调用。完成该实时调用后,才能进行任何后续离线层级调用。如果返回source:"live"且cacheStored:false,则停止并报告持久化失败,不要混用不同注册表代次。生成的回退结果可以继续用于规划,但不能用于执行。在明确指定的离线/无项目试运行中,立即添加--offline;如果两个层级都非空,则在同一工具轮次中同时启动 Core 和 Advanced 查询。不要探查status、文件系统或工作目录来再次确认已提供的上下文。如果仅凭 Core 就发现某项请求的操作需要 Advanced,则对所有此类未解决操作进行唯一一次 Advanced 调用。过期缓存或生成的回退结果仅供规划;执行需要在该次调用期间经过验证的实时注册表。 - 恰好执行一次精确查询轮次。 等待所有 Route Card 调用完成后,再构建唯一的精确 ID 命令。合并从所有层级和分支选出的 ID,并将集合扩展以涵盖每项修改、生产者、消费者、循环分支、不变量和验证;只能从返回的卡片中复制 ID。
在且仅在一次 shell 调用中发出一次多 ID 精确查询。领域查询的并行规则不适用于精确发现:不要将合并后的 ID 集拆分为并行或后续调用,也不要为原始任务要求添加后续精确查询。不要精确加载必要性取决于未来读取的条件性深入检查。将延后深入检查从精确选择器集合和调用计划中省略;在触发条件出现前,只在说明文字中记录其触发条件。调用计划中的路由必须能在当前阶段执行,因此绝不要添加目的含“if”或“when”的延后路由。在广泛扫描中,如果逐项 getter 的契约没有注明所需诊断信号,就无法弥补该缺口;应记录能力缺口,而不是选择该 getter。仅靠运行时选择器绑定,并不会使已知消费者变为条件性操作;将其契约纳入原始闭包。读取结果证明确有必要进行新的深入检查后,才将相关 ID 合并到至多一次的精简后续查询中。将
selected、related和denied视为一个封闭结果:selected和related是完整且可执行的契约,而denied条目是不可执行的策略记录,并非契约。将所有返回的 ID 从未解决集合中移除,绝不要仅为将某个 ID 提升为selected而查询它。related是完整的、直接且去重后的准备/回读层,不是递归扩展。被拒绝的请求意图属于终止状态:停止并报告阻塞,不要进入回退流程。针对任务特定信号的契约证据遵循封闭世界原则:通用结果容器或摘要不会承诺未明确注明的标记或字段。如果可执行契约包缺少所需能力或验证依据,或者某项限制阻碍了操作,则记录能力缺口,而不是探查是否存在更强大的内置功能。selected和related契约条目代表可用能力,并非必须调用;仅在对应请求涉及修改、前置条件或独立验证时使用。 - 规划具体调用。 将每项后置条件分配给最小的独立验证,并移除完全冗余的读取。去重契约,而非调用。明确的验证器限制具有权威性;只有当另一项通用读取自身的契约注明所需后置条件时,该读取才能消除限制,否则应记录验证缺口。不要将实质不同的参数值或用户指定的选择器合并到说明文字中:每种不同的参数分支都保留一个模板,每个明确指定的回读目标都保留一次调用;统一生成的序列可以保留为一次计数循环。计数式统一序列以其生成的第一个项作为具体模板。当生产者可以在请求指定的已知父级下创建对象时,应直接在该父级创建;不要再添加后续重新设置父级的修改。当参数行为按奇偶性等谓词分支时,应将每个分支的第一个成员作为模板;不要用任意后续样例替代。一个契约即可支持所有这些操作,无需进一步发现。除非任务或所选契约要求,否则不要添加推测性的存在性、冲突或覆盖预检查。默认值可以满足精确不变量,但不会使该不变量变成可选项:
新建的 Cube 已经恰好有一个
BoxCollider;应使用它,而不是再添加一个,但仍要将“恰好一个”保留为明确要求和验证义务。绝不能因当前值或默认值而省略明确请求的赋值:例如,用户要求设置现有碰撞体的m_IsTrigger时,即使其默认值已经匹配,也仍要规划component/modify。 - 将规划与执行分开。 试运行仍须规划所有受支持的请求修改;另行说明没有执行任何操作。静态批处理可以使用调用方定义的确定性路径。当 Unity 选择标识时,应单独执行生产者,并将消费者绑定到它返回的选择器,而不是预测名称。只有在可能执行修复时才发现修复方法;缺少规则时,诊断必须保持只读,且修复命令不得纳入领域选择、精确查询或调用计划。修改后发生传输故障会导致状态不确定:应先回读,绝不要盲目重复非幂等的创建、复制、销毁、导入或等效修改。
cs list-commands [--offline] --domain scene --domain objects --tier core --json
cs list-commands --offline --id gameobject/create --id gameobject/get --json
在返回的契约中,arguments: [] 表示没有命名参数;不要自行添加名为
args 的参数。只有实际的 command 请求才会使用外层 "args": {} 封装。
不要将 --domain 与 --id 混用;--tier 仅与域搭配使用。
如果要从相应视图精确加载 ID,请保留 --view control 或 --view custom;
编写 ID 使用默认视图。
仅进行规划或发现时,不要加载 references/commands.md;这些路由规则以及返回的
Route Cards 和 Contract Bundle 已完整覆盖所需信息。
调用 command 或 batch 前,请完整阅读一次 references/commands.md,以了解本次请求的
预检和重试协议。然后将准确的
{"id":"<canonical-id>","args":{...}} 写入必需的临时 JSON 文件,并运行
cs command --json --input <file>;即使 args 为空,也必须提供。
只能通过 list-commands 发现契约;切勿读取或搜索
scripts/cli、生成的注册表数据、路由元数据或 Python
实现文件来获取命令详情。这些文件属于非面向 Agent 的实现数据,体积可能远大于所选契约包。
只有在完整的内置计划存在明确缺口后,才进入回退流程。运行 cs catalog list,
加载建议的精确自定义契约,然后尝试 cs snippets search "<intent>",最后使用原始 exec。
对于回退前就能确定的要求,不要再返回内置发现;真正新增的要求允许进行一次范围有限的精确查询,并记录原因。如果没有可用的 Unity
项目,请将自定义契约和代码片段阶段标记为不可用,不要探测这些阶段。不可用的回退阶段不算已选中;不要加载其参考资料。
仅描述回退顺序并不代表已选中某个阶段。只有在即将执行该阶段文档所述操作之前,才加载相应参考资料。所选自定义契约查询是回退阶段中不受内置一次精确查询限制的例外。如果试运行在编写原始 C# 之前结束,则记录 exec 决策,无需读取 references/exec-code.md。
只有在用户明确要求更新命令列表时,才使用 cs list-commands --refresh …。
日常工作中不要加载或打印未经筛选的 62 条命令包注册表。
| Domain | 正向意图 | 排除/改用其他路由 |
|---|---|---|
editor | 编辑器状态、播放模式、测试运行、控制台维护 | 场景内容、对象选择、资源文件 |
scene | 场景列表/打开/保存及层级范围的读取,包括组件摘要 | 已识别 GameObject/组件的属性、预制件内容 |
objects | 对明确指定的场景 GameObject、组件、变换或选择执行操作 | 层级范围扫描、未知的未来目标、项目资源、预制件文件编辑 |
assets | 资源搜索/导入/CRUD、材质和 ScriptableObject | 场景层级、预制件内容 |
prefabs | 创建/实例化/解包预制件,或直接检查/编辑预制件内容 | 通用预制件枚举(assets/core)及无关资源路径 |
capture | 场景/Game 截图和 Profiler 录制 | 结构化状态检查 |
这五个控制平面契约不属于默认的编写视图。仅当用户请求的能力本身属于控制平面时,才使用
--view control --domain control --tier control-plane 检查它们。
仅为发现而使用 cs list-commands,并不能成为查询控制视图或加载或规划
command/list 契约的理由。
editor/menu.open 和 editor/window.open 属于拒绝策略意图,并非可执行契约。显式执行
list-commands --id 查询时,这些意图会显示在 denied 下,并标记 invoke=false;应将该结果归类为受阻并停止。切勿自动回退到代码片段或原始 exec 来处理这些意图。
调试正在运行的玩家
如果问题涉及玩家实际执行的操作,先打开运行时通道,再调查其他内容。cs health --mode runtime 会指出负责响应的进程。按命令优先的路由顺序检查状态;对于现有命令无法读取的状态,使用 cs exec --mode runtime --file <file>。
将正在运行的进程作为运行时状态的主要信息来源。如果无法执行,或问题涉及某个构建包含哪些代码,则检查日志、源代码和构建产物作为辅助证据。在可用时匹配构建 GUID,区分当前源代码与已发布的代码,并标明推断。仅凭子字符串匹配或文件时间戳,无法确定实际执行的是哪段代码。
如果编辑器中没有玩家所报告构建对应的编译集,运行时提交会被拒绝,并显示 [REPL ALIGNMENT REQUIRED]。立即请用户提供该构建的编译集 ZIP,并指出构建名称。默认情况下,该文件会导出为 CSharpConsoleCompileSet.zip,存放在构建机器上的构建输出目录旁边;Project Settings > C# Console 可以更改其路径或禁用导出。请构建该版本的人员提供匹配的 ZIP。如果已有候选文件,检查其构建 GUID 可作为有用证据;未经用户决定,不要注册该文件,也不要选择跳过。检查文件无法绕过运行时执行门槛。
读取玩家日志时,应先收集日志:cs logs --mode runtime --background 会返回所写入文件的路径,随后可在本地搜索该文件。前台跟踪会流式输出整个日志,包括着色器相关信息。
其他子命令
| 任务 | 子命令 | 详情 |
|---|---|---|
| 原始 C# 回退方案 | cs exec --file | references/exec-code.md |
| 可复用 C# | cs snippets … | references/snippets.md |
| 代码片段审计 | cs snippets doctor / stats | references/snippets-audit.md |
| 刷新并编译 | cs refresh | references/refresh.md |
| 就绪状态诊断 / 等待 | cs doctor / cs wait-ready | references/refresh.md |
| Unity Test Framework 运行 | cs test | references/tests.md |
| 编辑器日志检查 | editor/console.mark + 本地读取 | references/logs.md |
| 正在运行的玩家及其文件 | --mode runtime / cs pull | references/player.md |
| 为玩家的构建进行编译 | cs compile-set | references/player.md |
| 监视日志写入过程 | cs logs | references/player.md |
| 自定义命令目录 | cs catalog sync / list | references/catalog.md |
| 软件包 / 连接状态 | cs status / cs health | references/status.md |
| 软件包设置 | cs setup | references/setup.md |
输出约定
- 对
command、list-commands和batch使用--json。在默认紧凑格式下,检查ok和 CLI 进程退出状态。仅在诊断时添加--verbose;其完整封装还会显示exitCode,该值必须与进程状态一致。 - 其他子命令会输出更精简的文本格式。仅在确实需要结构化封装时,才为
exec添加--json。 - 版本不匹配表示已安装的软件包和 CLI 使用不同的
major.minor版本线;在两者一致之前,所有会驱动 Unity 的命令都会被拒绝(退出码为 1)。cs setup和cs status不受此限制,以便修复并查看不匹配情况;不会连接到 Unity 的命令(cs doctor、cs wait-ready、离线列表)不受影响。请遵循references/setup.md。 - 展开的 CLI 命令和 JSON 载荷仅供 Agent 内部使用。必须打开或聚焦 Unity 时,用通俗语言告诉用户需要执行什么操作,然后自行运行
cs status验证结果。