Unity CLI
A CLI tool for controlling Unity Editor from the command line.
Overview
Execute Unity Editor operations from CLI: Play Mode control, console log retrieval, test execution, scene/GameObject manipulation, and more.
# Play Mode control
u play
u stop
# Get console logs (error and above)
u console get -l E
# Execute menu items
u menu exec "Assets/Refresh"
# Execute ContextMenu
u menu context "DoSomething" -t "/Player"
Key features:
- Execute Unity Editor operations from CLI
- Support for MenuItem / ContextMenu execution
- Simultaneous control of multiple Unity instances
- Domain reload resilience (auto-reconnection)
- UI Toolkit VisualElement tree inspection (dump, query, inspect, click, scroll, text)
- Dynamic API invocation (
u api call/schema— 5,243+ Unity static methods) - Monkey testing (
u uitree monkey) and structural snapshots (u uitree snapshot) - Open projects with appropriate version (Unity Hub integration)
- Project information retrieval (no Relay Server required)
Requirements
- uv (Python package manager)
- Python 3.11+
- Unity 2022.3+
- Unity Hub (for
open/editorcommands)
Quick Start
1. Unity Setup
Add the UnityBridge package to your Unity project:
# Via OpenUPM (recommended)
openupm add com.bigdra50.unity-bridge
# Or via git URL
# Window > Package Manager > + > Add package from git URL...
# https://github.com/bigdra50/unity-cli.git?path=UnityBridge
2. Connection
In Unity Editor, open Window > Unity Bridge:
- Click Start Server (launches Relay Server)
- Click Connect (Unity → Relay connection)
The toolbar indicator (right side) shows connection status and allows toggle via click.
3. CLI Operations
# Run directly with uvx (no installation required)
uvx --from git+https://github.com/bigdra50/unity-cli u state
# Play Mode control
uvx --from git+https://github.com/bigdra50/unity-cli u play
uvx --from git+https://github.com/bigdra50/unity-cli u stop
# Get console logs (error and above)
uvx --from git+https://github.com/bigdra50/unity-cli u console get -l E
Installation
# Global installation
uv tool install git+https://github.com/bigdra50/unity-cli
# With interactive UI (editor selection prompt)
uv tool install "git+https://github.com/bigdra50/unity-cli[interactive]"
# CLI commands (both aliases work the same)
unity-cli state # Full name
u state # Short alias
u play
u console get -l E | head -10 # Last 10 error+ logs
# Run Relay Server standalone
unity-relay --port 6500
CLI Commands
Version
u version # Show CLI version
Shell Completion
# Zsh
u completion -s zsh > ~/.zsh/completions/_unity-cli
# Bash
u completion -s bash >> ~/.bashrc
# Fish
u completion -s fish > ~/.config/fish/completions/unity-cli.fish
# PowerShell
u completion -s powershell >> $PROFILE
Open Project
# Open project with appropriate version (reads ProjectVersion.txt)
u open ./MyUnityProject
# Specify editor version
u open ./MyUnityProject --editor 2022.3.10f1
# Non-interactive mode (for CI/scripts)
u open ./MyUnityProject --non-interactive
# Wait until exit
u open ./MyUnityProject --wait
Editor Management
# List installed editors
u editor list
# Install editor
u editor install 2022.3.10f1
# Install with modules
u editor install 2022.3.10f1 --modules android ios webgl
# Install non-release version with changeset
u editor install 6000.1.0a1 --changeset abc123
Project Information (No Relay Server Required)
# Full project info
u project info ./MyUnityProject
# Unity version only
u project version ./MyUnityProject
# Package list
u project packages ./MyUnityProject
u project packages ./MyUnityProject --include-modules # Include built-in modules
# Tags & layers
u project tags ./MyUnityProject
# Quality settings
u project quality ./MyUnityProject
# Assembly Definition list
u project assemblies ./MyUnityProject
# JSON output
u --json project info ./MyUnityProject
Basic Operations (via Relay Server)
# Check editor state
u state
# Play Mode control
u play
u stop
u pause
# Console logs
u console get # All logs (plain text)
u console get --json # All logs (JSON format)
u console get -s # All logs with stack traces
u console get -l W # Warning and above (warning, error, exception)
u console get -l E # Error and above (error, exception)
u console get -l +W # Warning only
u console get -l +E+X # Error and exception only
u console get | head -20 # Last 20 entries
u console get | grep "error" # Filter by text
u console clear # Clear console
# Asset refresh
u refresh
# Editor selection
u selection
# Screenshot (capture is default, --burst for burst mode)
u screenshot # GameView (default)
u screenshot -s scene # SceneView
u screenshot -s camera # Camera.Render
u screenshot -p ./output.png # Custom path
u screenshot --super-size 2 # 2x resolution (game only)
u screenshot -s camera -c "Main Camera" -W 1920 -H 1080
u screenshot --burst -n 10 # Burst: 10 frames
u screenshot --burst -n 5 -f jpg -q 80 # Burst with format/quality
# Pipe-friendly: outputs path only when piped
u screenshot -s game | mcat -i # Inline display in terminal
u screenshot -s game | pbcopy # Copy path to clipboard
u screenshot -s game | xargs open # Open with default viewer
Instance Management
# List connected instances
u instances
# Specify target instance
u --instance /Users/dev/MyGame state
u --instance /Users/dev/Demo play
Test Execution
# EditMode tests
u tests run edit
# PlayMode tests
u tests run play
# Filtering
u tests run edit --test-names "MyTests.SampleTest"
u tests run edit --group-pattern ".*Integration.*"
u tests run edit --categories "Unit" "Integration"
u tests run edit --assemblies "MyGame.Tests"
# Fire and forget
u tests run edit --no-wait
# List available tests
u tests list edit
u tests list play
# Check running test status
u tests status
Scene Operations
# Active scene info
u scene active
# Hierarchy
u scene hierarchy # Root only (depth 1)
u scene hierarchy --depth 2 # Up to 2 levels
u scene hierarchy --page-size 100 # Custom page size
# Scene operations
u scene load --name MainScene
u scene load --path "Assets/Scenes/Sub.unity" --additive
u scene save
u scene save --path "Assets/Scenes/NewScene.unity"
GameObject Operations
# Find
u gameobject find "Main Camera"
u gameobject find "Player" --iterate-all
# Create
u gameobject create --name "MyCube" --primitive Cube --position 0 1 0
# Modify
u gameobject modify --name "MyCube" --position 5 0 0 --rotation 0 45 0
# Delete
u gameobject delete --name "MyCube"
Component Operations
# List components
u component list -t "Main Camera"
# Inspect component
u component inspect -t "Main Camera" -T Camera
# Add component
u component add -t "Player" -T Rigidbody
# Remove component
u component remove -t "Player" -T Rigidbody
Menu / ContextMenu
# Execute menu
u menu exec "Edit/Play"
u menu exec "Assets/Refresh"
u menu exec "Window/General/Console"
# List menus
u menu list # All menus
u menu list -f "Assets" # Filter
u menu list -f "Play" -l 20 # Limit count
# Execute ContextMenu (scene objects)
u menu context "Reset" -t "/Player"
# Execute ContextMenu (ScriptableObject)
u menu context "DoSomething" -t "Assets/Data/Config.asset"
# Execute ContextMenu (Prefab)
u menu context "Initialize" -t "Assets/Prefabs/Enemy.prefab"
Asset Operations
# Create Prefab
u asset prefab -s "Player" -p "Assets/Prefabs/Player.prefab"
# Create ScriptableObject
u asset scriptable-object -T "GameConfig" -p "Assets/Data/Config.asset"
# Asset info
u asset info "Assets/Data/Config.asset"
UI Toolkit Tree Inspection
Inspect and interact with UI Toolkit VisualElement trees. Uses ref IDs for element targeting.
# List panels / dump tree
u uitree dump
u uitree dump -p "PanelSettings" --json
# Query elements (AND conditions)
u uitree query -p "PanelSettings" -c "action-btn"
# Inspect
u uitree inspect ref_3 --style --children
# Interact
u uitree click -p "PanelSettings" -n "BtnStart"
u uitree text -p "PanelSettings" -n "ScoreLabel"
u uitree scroll -p "PanelSettings" -n "ScrollView" --y 500
# Monkey test (random interactions + error monitoring)
u uitree monkey -p "PanelSettings" -c "action-btn" --count 50 --seed 42
# Structural snapshots (save/diff/list/delete)
u uitree snapshot save -p "PanelSettings" --name baseline
u uitree snapshot diff -p "PanelSettings" --name baseline
Dynamic API Invocation
Call any Unity public static method via reflection. 5,243+ methods available.
# Search methods
u api schema --type AssetDatabase
u api schema --namespace UnityEditor --limit 20
# Call methods
u api call UnityEngine.Application get_unityVersion
u api call UnityEditor.AssetDatabase Refresh
u api call UnityEditor.EditorApplication ExecuteMenuItem --params '["Window/General/Console"]'
# Offline schema (cached per Unity version)
u api schema --offline --type PlayerSettings
Frame Recording
# Start recording (camera-based, configurable FPS/format/resolution)
u recorder start --fps 30 -f jpg -q 80
u recorder start --fps 60 -W 1920 -H 1080 -o ./frames
# Stop recording and get results
u recorder stop
# Check recording status
u recorder status
Configuration
# Show current configuration
u config show
# Generate default .unity-cli.toml
u config init
u config init -o ./custom-config.toml
u config init --force # Overwrite existing
Options
Common Options
| Option | Description | Default |
|---|---|---|
--relay-host |
Relay Server host | 127.0.0.1 |
--relay-port |
Relay Server port | 6500 |
--instance, -i |
Target Unity instance | default |
--timeout, -t |
Timeout (seconds) | 10.0 |
--json, -j |
Output JSON format | false |
--quiet, -q |
Suppress success messages | false |
--verbose |
Show request/response on stderr | false |
Tests Options
| Option | Description |
|---|---|
--test-names, -n |
Test names (exact match) |
--group-pattern, -g |
Regex pattern for test names |
--categories, -c |
NUnit categories |
--assemblies, -a |
Assembly names |
--no-wait |
Return immediately without waiting for results |
Scene Hierarchy Options
| Option | Description | Default |
|---|---|---|
--depth, -d |
Hierarchy depth | 1 (root only) |
--page-size |
Page size | 50 |
--cursor |
Pagination cursor | 0 |
Exit Codes
| Code | Name | Description |
|---|---|---|
| 0 | SUCCESS | Command completed successfully |
| 1 | USAGE_ERROR | Invalid arguments or validation failure |
| 2 | TRANSIENT_ERROR | Retryable: instance reloading, busy, timeout |
| 3 | CONNECTION_ERROR | Relay Server not running or unreachable |
| 4 | OPERATION_ERROR | Command failed (instance not found, protocol error, etc.) |
| 5 | TEST_FAILURE | Tests ran but some failed |
u state; echo $? # 0 = connected, 3 = relay not running
u tests run edit; echo $? # 0 = all passed, 5 = some failed
u play --quiet 2>/dev/null; echo $? # Suppress output, check exit code only
Environment Variables
| Variable | Description |
|---|---|
UNITY_CLI_QUIET |
Set to 1 to suppress success messages |
UNITY_CLI_VERBOSE |
Set to 1 to log request/response to stderr |
UNITY_CLI_JSON |
Set to 1 for JSON output by default |
UNITY_CLI_NO_PRETTY |
Set to 1 to disable Rich formatting |
NO_COLOR |
Set to disable colors (standard) |
AI Agent Skills
Workflow skills for AI coding agents (Claude Code, Codex, Gemini CLI, Cursor, GitHub Copilot, Windsurf, etc.). Conforms to the agentskills.io spec.
Option 1: GitHub CLI (recommended, gh 2.90.0+)
# Interactive: pick skills from a list
gh skill install bigdra50/unity-cli
# Install a single skill
gh skill install bigdra50/unity-cli unity-verify
# Install all skills at once (Claude Code, user scope)
for s in unity-shared unity-verify unity-debug unity-build \
unity-scene unity-asset unity-perf unity-ui unity-api; do
gh skill install bigdra50/unity-cli "$s" --agent claude-code --scope user
done
# Pin to a specific release
gh skill install bigdra50/unity-cli unity-verify --pin v3.11.0
Supports 40+ agents via --agent (claude-code, github-copilot, cursor, codex, gemini-cli, ...). Default scope is project; use --scope user for global install.
Option 2: Skills CLI (cross-agent, no gh required)
# Install all skills (project-local)
npx skills add github:bigdra50/unity-cli
# Install globally (user-level)
npx skills add github:bigdra50/unity-cli -g
# Install specific skills only
npx skills add github:bigdra50/unity-cli -s unity-ui unity-api
See Skills CLI for details.
Option 3: Manual (git clone)
git clone https://github.com/bigdra50/unity-cli.git
# Single skill
cp -r unity-cli/skills/unity-verify ~/.claude/skills/
# All skills
cp -r unity-cli/skills/* ~/.claude/skills/
Skills
| Skill | Description |
|---|---|
unity-verify |
Compile & test validation (refresh → error check) |
unity-debug |
Error investigation |
unity-build |
Build pipeline |
unity-scene |
Scene construction |
unity-asset |
Asset & dependency management |
unity-perf |
Profiler analysis |
unity-ui |
UI testing (uitree + monkey + snapshot → PlayMode) |
unity-api |
Dynamic API invocation (5,243+ methods) |
unity-shared |
Common rules (loaded automatically by other skills) |
Recipes
See docs/recipes.md for piping, scripting, and tool composition examples.
u screenshot -s game | mcat -i # Inline display in terminal
u console get -l E | head -10 # Last 10 errors
u instances --json | jq -r '.[].instance_id' # Extract paths
Architecture
flowchart TB
subgraph CLI["u (Python)"]
direction TB
RC[RelayConnection: TCP communication]
EB[Exponential Backoff: 500ms → 8s]
RID[request_id: idempotency guarantee]
end
subgraph Relay["Relay Server (Python)"]
direction TB
IR[InstanceRegistry: multiple Unity management]
Cache[RequestCache: idempotency cache]
HB[Heartbeat: Single Outstanding PING]
Q[Queue: FIFO max 10]
end
subgraph Unity["UnityBridge (C#)"]
direction TB
Client[RelayClient: connection management]
Dispatcher[CommandDispatcher: BridgeTool attribute]
Reload[BridgeReloadHandler: reconnection]
end
CLI -->|TCP:6500| Relay
Relay -->|TCP:6500| Unity
Protocol Specification
See docs/protocol-spec.md for details.
- Framing: 4-byte big-endian length + JSON
- State Machine: DISCONNECTED → READY → BUSY → RELOADING
- Heartbeat: 5s interval, 15s timeout (3 retries)
- Retry: Exponential Backoff (500ms → 8s, max 30s)
Troubleshooting
# Check if Relay Server is running
lsof -i :6500 # macOS / Linux
netstat -ano | findstr :6500 # Windows
# Check connected instances
u instances
# Check Unity console for errors
u console get -l E
v2.x → v3.0 Migration
| Change | v2.x | v3.0 |
|---|---|---|
| Command name | unity-mcp |
unity-cli |
| Connection target | Unity direct (6400) | Relay Server (6500) |
| Protocol | 8-byte framing | 4-byte framing |
| Multiple instances | Not supported | Supported |
# v2.x
unity-mcp --port 6400 state
# v3.0
u state # Via Relay
u --instance /path/to/project state # Specific instance
License
MIT License
No comments yet
Be the first to share your take.