About unity-batch
unity-batch provides Unity skills and an HTTP endpoint for querying objects, previewing bulk edits, and executing sequences of different skills. It includes execution reports and asynchronous job handling for larger or longer-running operations.
Key features
- 01Query GameObjects, components, and assets
- 02Preview bulk edits before execution
- 03Compose up to 50 skill calls in one request
- 04Track jobs and retrieve execution reports
- 05Retry failed steps or operations
Use cases
- 01Preview and apply scene-wide property changes
- 02Create objects and add components in sequence
- 03Review results of long-running bulk edits
- 04Retry failed steps without repeating successful ones
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ besty0728/ unity-skills --skill unity-batchAfter installing, type/unity-batchin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
reference/batch_cleanup_temp_objects.mdbatch_execute.mdbatch_fix_missing_scripts.mdbatch_preview_rename.mdbatch_preview_replace_material.mdbatch_preview_set_property.mdbatch_query_assets.mdbatch_query_components.mdbatch_query_gameobjects.mdbatch_replace_material.mdbatch_report_get.mdbatch_report_list.mdbatch_retry_failed.mdbatch_set_render_layer.mdbatch_standardize_naming.mdbatch_validate_scene_objects.mdjob_cancel.mdjob_list.mdjob_logs.mdjob_progress.mdjob_status.mdjob_wait.mdDetails
From the project READMETriggers
- Operating on many objects at once
- Running or polling long async jobs
- Preview-then-commit bulk edits
- 一次性操作大量对象、运行或轮询长时异步任务、先预览后提交的批量编辑
Unity Batch Skills
The POST /skills/batch endpoint, query → preview → execute bulk edits, execution reports and async jobs. Parameters come from the schema, never from a skill's name; execution and dryRun rules: root SKILL.md.
POST /skills/batch — several skills, one HTTP call
An HTTP endpoint, not a skill: never send skills_batch to POST /skill/<name>. It runs up to 50 ordinary skill calls in order inside one main-thread job, each through the full single-skill pipeline (validation, permission gate, its own Undo group, audit): one round trip and one main-thread wake-up instead of N, the biggest saving once there are 3+ writes.
POST /skills/batch
{
"steps": [
{"skill": "gameobject_create", "args": {"name": "Cube", "primitiveType": "Cube"}},
{"skill": "component_add", "args": {"instanceId": {"$ref": "$0.instanceId"}, "componentType": "Rigidbody"}}
],
"continueOnError": false
}
| Body field | Default | Meaning |
|---|---|---|
steps | required | {skill, args} objects, in order. More than 50 → 400 SEMANTIC_INVALID; split the call. |
continueOnError | false | false = stop at the first failure; true = record it and keep going. |
params | none | Values for {"$param":"name"} or {"$param":"name","default":X} nodes in args; static, resolved before $ref; a missing slot without default fails that step. |
$ref: an args object whose only key is$ref,{"$ref":"$N.path"}, is replaced by the value atpath(e.g.instanceId,results[0].path; bare$N= the whole result) in the result of earlier successful stepN(0-based). Only structured args are scanned, never strings. A ref that cannot resolve (forward, failed step, no match) fails its step withSEMANTIC_INVALID. Refer to created objects through$ref(instanceId, orentityIdon Unity 6000.4+) rather than by name: a same-named existing object may win a name lookup.- Query:
?mode=dryRun(the batch dryRun gate) validates every step, executes nothing and never halts; a step may name an object an earlier step would create (a warning notes the skipped live checks) and$refargs get a structural check only (refsValidated).?mode=transactionalis all-or-nothing with Undo rollback, rejected up front (400) for an unknown skill, a step that may trigger a domain reload, orcontinueOnError:true.?diff=1adds a netsceneDiff;?wire=v2slims dryRun step payloads;expectInstance/expectProjectwork as on/skill.?mode=planis not supported.mode/dryRunmay sit in the body instead: each key resolves query-first and a blank value counts as absent. Any key outside these (body:steps,params,continueOnError,mode,dryRun) is400 UNKNOWN_PARAM.
Reading the response. HTTP 200 whenever the batch ran; only a rejected request (bad body, >50 steps, unknown mode or key) is 4xx.
{"status":"partial","mode":"execute","dryRun":false,"executed":2,"failed":1,
"results":[{"index":0,"skill":"...","status":"success","result":{...}},
{"index":1,"skill":"...","status":"error","error":{"errorCode":"...","error":"..."}},
{"index":2,"skill":"...","status":"skipped"}]}
status:completed(nothing failed),partial, orrolled_back(transactional: executed steps becomerolled_back, asset-writing ones flaggedrollbackReliability:"partial").mode/dryRunecho what actually ran; every entry carriesindexandskill.- Partial failure:
successsteps are applied; the failed step's Undo-recorded changes are reverted;skippedsteps never ran. Resend only the fixed failed step and the skipped ones, never the successful ones. - Authorization always interrupts,
continueOnErrornotwithstanding: aMODE_RESTRICTED/CONFIRMATION_REQUIREDstep halts the batch and returns its full payload (grant token included); complete the grant, then resubmit the remaining steps.
Not the same as
batch_execute.batch_execute(confirmToken)commits one previewed bulk operation (one verb over N objects).POST /skills/batchcomposes N different skills over any targets and takes no token; it never skips the preview/confirm gate — abatch_executestep still needs its ownconfirmToken.
Jobs. When a skill or step returns a jobId (async execution, tests, compiles), wait with GET /jobs/{id}?wait=<s> (up to 120 s; answers once the job is terminal, with resultData; waitTimedOut:true = GET it again; a 503 during a domain reload = repeat the same URL) or poll GET /jobs/{id}. Both stay out of the main-thread skill queue and are far smaller than job_status; job_wait blocks the main thread (max 2 s).
Preview → execute
- Select with
queryJson(filters ANDed:namesubstring,namePatternregex,path/parentPathexact,entityId,instanceId,tag,layer,componentType,sceneName,active,isStatic,prefabSource,includeInactive(false),limit(500));batch_query_*shows what matches. - Preview with
batch_preview_*or a fixer (batch_fix_missing_scripts,batch_standardize_naming,batch_set_render_layer,batch_replace_material,batch_cleanup_temp_objects). Previews are read-only and return{confirmToken, kind, summary, riskLevel, targetCount, executableCount, skipCount, sampleChanges: [{targetPath, action, before, after}], skipReasons}. - Review samples and risk (execution may delete or modify many objects), then
batch_execute(confirmToken). The token is single-use and expires after an hour: preview again. Large runs return ajobId; the report (batch_report_get) lists failures, andbatch_retry_failed(reportId)reruns only those.
Under the guide surface profile previews still work but carry surfaceExclusion; batch_execute then returns SURFACE_EXCLUDED without consuming the token.
Operating Mode
All but four of the 22 skills are read-only SemiAuto (query, preview, fixers, validation, reports, job status/progress/logs/list) and run directly under Approval; the 4 FullAuto ones (batch_execute, job_wait, job_cancel, batch_retry_failed) answer MODE_RESTRICTED there first and need a grant. Auto/Bypass run all; none is NeverInSemi → operating mode.
Skills Overview
- Query:
batch_query_gameobjects,batch_query_components,batch_query_assets(type/folder/name regex/label). - Preview:
batch_preview_rename(prefix/suffix/replace/regex_replace),batch_preview_set_property,batch_preview_replace_material, plus the fixers above;batch_validate_scene_objectsonly reports (missing scripts/references, duplicate names, empty objects). - Execute and reports:
batch_execute,batch_retry_failed,batch_report_get,batch_report_list. - Jobs:
job_status,job_progress,job_logs,job_list,job_wait,job_cancel.
Per-skill tables and result shapes: reference/<skill_name>.md — rarely needed, the schema notes the parameters.
DO NOT (common hallucinations):
batch_executecannot run without aconfirmTokenfrom a preview or fixer callbatch_rundoes not exist → usebatch_execute(confirmToken)job_poll/job_resultdo not exist → useGET /jobs/{id}(orjob_status) for state;job_status'sresultHintnames the skill that returns a large resultbatch_delete/batch_movedo not exist → useasset_*skills for asset-level operations
Elsewhere: asset bulk move/copy/delete → asset_*; workflow session undo → workflow_*.
Exact Signatures
There is no Batch category: GET /skills/schema?category=Workflow holds 16 of these skills (query, preview, execute, reports, jobs) and ?category=Validation the 5 fixers plus batch_validate_scene_objects; or use ?names=a,b.