agentleFS
ArkTarusovArkTarusov/unity-cli-plugin/skills/unity-pipeline/SKILL.md

unity-pipeline

Skill7 starsChanged 4 months agoMITView on GitHub

Use when automating a running Unity Editor from the terminal via UnityCLI — entering play mode, running builds or tests, executing editor commands for scenes, GameObjects, prefabs, assets, materials, or settings, adding or removing UPM packages in the running Editor, polling build/recompile/bake status — or when `unity command` or `unity status` reports no connected Editor or a missing Pipeline package, or the Editor hangs or shows a modal dialog.

2 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions2 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 2

    1. Unity-Technologies/skills★ 1.2ksame name
    2. keijiro/unity-skills★ 11same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository2 other files it gives its agents.

The file

We split this skill into the rules it gives an agent

1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Verify the echo: Every response carries data.parameters — the arguments the server actually received.

    line 22

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Driving the Unity Editor via UnityCLI

The Unity Pipeline package (com.unity.pipeline) runs a local HTTP server inside the Editor; unity command executes commands against it live — no relaunch, no batch mode. The exposed surface is full authoring (scenes, GameObjects, prefabs, materials, animation, script creation, packages, tests, builds) — the same command set MCP-based Unity integrations wrap, reachable without an MCP bridge. Prerequisite basics (PATH, --json, auth): see skill unity-cli-core.

Argument syntax — the #1 source of silent failures

The only working form is --flag value with snake_case names:

unity command set_transform --gameobject Player --position "[1,2,3]"

Every other form — key=value, positional, -- key=value, kebab-case (--save-path) — is dropped silently: the command reports success and runs with defaults. Verified failure mode: a click command "succeeds" while clicking at (0,0); a path=... argument becomes a literally-named folder. Missing required parameters do fail loudly (400) — only unknown/malformed forms vanish.

Two mandatory habits:

  1. Verify the echo. Every response carries data.parameters — the arguments the server actually received. After any mutating or surprising call, check your arguments are in there. An empty parameters: {} when you passed arguments means they were dropped.
  2. Verify the schema on doubt. Argument names are not uniform across commands (delete_asset --asset, but open_scene --path). references/editor-commands.md lists the core commands with arguments; on a mismatch, the live truth is unity --json command (full JSON schemas, per-project).

Prerequisites — check, don't install

Live control needs BOTH: UnityCLI on the machine AND the Unity Pipeline package (com.unity.pipeline) inside the target project. The CLI alone can install/open editors but cannot talk to a running Editor.

  1. unity status — is an Editor running? GUI editors only: an editor launched with -batchmode serves commands but never appears here — probe it with unity command --project-path <path> instead.
  2. unity pipeline list — does the project show Pipeline: Installed?

If the package is missing, stop and ask the user — do not run the install to unblock yourself. unity pipeline install edits the project's Packages/manifest.json and triggers a recompile: a project change that lands in version control. Propose the exact command (unity pipeline install --project-path <path>; requires unity auth login) and continue only after approval. Same rule for unity pipeline upgrade. unity pipeline list-versions shows available versions.

Discover, then execute

unity status                     # connected Editors: port, project, version, PID, state
unity command                    # list commands the Editor exposes (or: unity list)
unity command <name> --param value ...
  • The command list is dynamic and incomplete. It depends on package version, project code, and installed packages — and ten RuntimeOnly commands (simulate_pointer, simulate_key, runtime_status, capture_runtime_element, set_timescale, set_target_framerate, quit, log, hotreload_status, cleanup_hotreload), intended for Player connections (--runtime), are filtered out of the editor listing yet execute fine against the editor (capture_runtime_element only exists on Unity 6000.7+). Their schemas exist only in references/editor-commands.md (section "RuntimeOnly commands") — the CLI cannot show them. Absence from the list proves nothing; a genuinely unknown name fails with exit code 6 and prints the available list.
  • Projects can define their own commands: a static method with [CliCommand]/[CliArg] attributes auto-registers after compilation, schema included (references/eval-recipes.md).
  • Multiple Editors open → disambiguate with --project-path <path> (env UNITY_PROJECT_PATH).
  • Slow operations → raise --timeout <seconds> (default 30).
  • --json wraps results as {success, command, data: {parameters, result}}.

Play-mode state is verified with editor_status (its playMode field) — editor_play/editor_stop only mutate.

Conventions the commands follow

ConventionMeaning
--confirm trueDestructive commands (delete_asset, set_player_settings, package_add/remove, clears/bakes) refuse to run without it
--dry_run truePreview what a mutating command would do, without doing it
Async + status pollingLong operations return immediately; poll their status command: build→build_status, recompile→recompile_status, run_tests→test_status, bakes→*_bake_status, switch_build_target→switch_build_target_status, packages→package_status
Authoring rootFile/asset-creating commands resolve and confine bare paths under a base folder inside Assets/; get_authoring_root / set_authoring_root --root Assets for full project access
Recompile before usecreate_script produces a type only after recompile completes — poll recompile_status, then attach_script. Files written by anything other than pipeline commands (shell, external tools) stay invisible to the AssetDatabase until eval AssetDatabase.Refresh() (references/eval-recipes.md); write_text_file imports what it writes itself
Main-thread-free subsetconsole and all *_status poll commands respond even while the Editor main thread is busy — use them to tell "busy" from "stuck" (references/lifecycle-recovery.md)

Scene changes lose data silently

open_scene (and API-level EditorSceneManager.OpenScene) discards unsaved changes without any prompt. Protocol before replacing scenes: list_open_scenes → any isDirty scene → save_all, or explicitly decide to discard; if the dirty work isn't yours, ask. Details and editor shutdown/recovery: references/lifecycle-recovery.md.

Hangs and modal dialogs

A modal dialog blocks the Editor main thread: commands time out while unity status still reports ready (heartbeat needs no main thread). Diagnosis table, dialog inventory, prevention, clean-shutdown (save_all + eval EditorApplication.Exit(0)), and crash-recovery procedure: references/lifecycle-recovery.md.

Verification and capture

  • State read while the Editor is playing measures whatever Update wrote last frame — for stable assertions, read with play mode stopped.
  • capture_game_view renders a camera to PNG (base64 inline by default, --save_path for a file); capture_scene_view renders the Scene View; screenshot --view game|scene captures the actual view to a file. UI on a Screen Space Overlay canvas is not part of any camera's render — camera-based capture misses it.
  • simulate_pointer / simulate_key drive a virtual Input System device (hidden from the listing — schemas in references/editor-commands.md). Passing arguments in any form other than --x 10 --y 20 silently clicks at (0,0) — the argument-drop trap above. If gameplay code still doesn't react (e.g. it polls a specific device), queue state on the real device via eval (references/eval-recipes.md).

Tests

Against a running Editor: unity command run_tests --mode all|editor|playmode (async with --async_tests true, poll test_status). Headless unity test uses different mode names: --mode EditMode|PlayMode. The two are not interchangeable.

Headless (no running Editor)

These spawn an editor in batch mode instead of connecting to one:

unity build . --target StandaloneWindows64 --execute-method Builder.PerformBuild -o ./out
unity test . --mode EditMode --filter "MyNamespace" --output results.xml --timeout 1800
unity run . -- -executeMethod Tool.Run -quit      # raw editor args after --
unity run . --command my_command -- --arg value   # registered command, one-shot: boots, runs, exits
  • unity build requires --execute-method — Unity has no built-in command-line build.
  • --allow-install downloads and installs the project's editor version if missing — multi-gigabyte; don't pass it without the user's OK.
  • unity test writes an NUnit XML report; set --timeout or a hung run never exits.
  • unity run --command mixes the editor log into stdout — parse with --format ndjson.
  • Against a running Editor, prefer unity command build / unity command run_tests (async, editor stays open).

Resident headless editor (agent / SSH build box)

For many commands against one project, a fresh batch boot per command is wasteful. Launch the editor binary with -batchmode and no -quit — it loads the project, stays resident, and serves the Pipeline API like a GUI editor (~sub-second round-trips, no domain reload per call):

"<editor-binary>" -batchmode -projectPath <project> -logFile editor.log &
# PowerShell: Start-Process "<editor-binary>" -ArgumentList '-batchmode','-projectPath','<project>','-logFile','editor.log'
unity command --project-path <project>       # reachability probe + command list
  • Such an editor is invisible to unity status and unity editors running (its lockfile heartbeat differs from a GUI editor's) — always target it via --project-path and probe with unity command/unity list, never status.
  • A bare unity run <project> (no --command) is NOT a way to get one: batch runs to completion and exits.
  • Any resident editor — batch or GUI — holds a license seat until it exits; one-shot unity run --command releases it on exit.
  • Binary paths per install: unity editors -i (the location field). Launching directly also sidesteps unity open EBUSY failures (references/lifecycle-recovery.md).

Common mistakes

MistakeReality
Passing key=value, positional, or kebab-case argumentsSilently dropped; command "succeeds" with defaults. Only --snake_case value works; check the parameters echo
Firing build/bake/run_tests and treating the immediate return as completionThey queue; only the *_status command tells the outcome (full BuildReport in build_status)
"Command absent from the list → it doesn't exist"The list is per-project AND hides some registered commands; a truly unknown name exits with code 6
Switching scenes without checking isDirtyopen_scene silently discards unsaved changes
Writing assets outside the authoring rootPaths are confined under it; check get_authoring_root, widen with set_authoring_root only when intended
Using unity build while an Editor already runs on the projectSpawning a second editor instance fails or fights the open one; use unity command build against the running Editor
Play-mode/domain-reload race after package_add or script editsPoll recompile_status before the next command
Treating unity status: ready as "Editor is responsive"It only means the server process is alive; the main thread may be stuck — see references/lifecycle-recovery.md
Concluding "no Editor" from an empty unity statusA -batchmode editor serves commands but never registers in status — probe unity command --project-path <path> before spawning a new editor

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.