CSharp Console

April 27, 2026 · View on GitHub

CSharp Console

Interactive C# REPL for Unity — powered by Roslyn

License Unity Claude Code UPM

Execute C# code on the fly in Unity Editor & Runtime — no compilation wait, no boilerplate,
full access to your project's live state. Editor zero-config, Runtime just works with HybridCLR.

Features · Installation · Quick Start · REPL Usage · Extending Commands

English | 中文


✦ Features

Core Capabilities

FeatureDescription
>_Interactive REPLRoslyn-based script submissions with persistent session state — variables, using directives, and types survive across executions
#Top-level SyntaxWrite statements directly. No class, no Main, no boilerplate
@Command FrameworkExtensible [CommandAction] commands with automatic JSON-to-parameter binding (positional & named args), /batch endpoint for multi-command workflows
TabSemantic CompletionReal-time member, namespace, and type completions directly from Roslyn
🔓Private Member AccessBypass private / protected / internal access modifiers at compile time for deep inspection
Debug While PausedSubmit code while the Editor is paused in Play Mode — inspect transient state captured at the exact frame, without losing the snapshot
📡Remote ExecutionCompile in the Editor, execute on a connected Player build (IL2CPP via HybridCLR)

How It Looks

Immediate evaluation — no class, no Main, just code

DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")

Cross-submission state — variables survive across submissions

var cam = Camera.main; cam.transform.position

Private member access — bypass access modifiers at compile time

var go = GameObject.Find("Main Camera");
go.m_InstanceID

LINQ over live scene objects

string.Join(", ", UnityEngine.Object.FindObjectsOfType<Rigidbody>().Select(x => x.name))

Command expressions — invoke server-side commands directly

@editor.status()

⚙ Installation

Add via Packages/manifest.json:

{
  "dependencies": {
    "com.zh1zh1.csharpconsole": "https://github.com/niqibiao/unity-csharpconsole.git"
  }
}

Or reference as a local package:

{
  "dependencies": {
    "com.zh1zh1.csharpconsole": "file:../com.zh1zh1.csharpconsole"
  }
}

Note: Both assembly definitions have autoReferenced: false. If your code needs to reference this package, add Zh1Zh1.CSharpConsole.Runtime (or .Editor) to your asmdef's references explicitly.

▶ Quick Start

Editor — Zero Configuration

Import the package and it just works. The Editor-side HTTP service starts automatically via [InitializeOnLoadMethod] — no initialization code, no settings to tweak, no manual setup. Open the REPL from the Unity menu:

Menu ItemTarget
Console > C#ConsoleLocal Editor
Console > RemoteC#ConsoleRemote Editor / Player

Runtime — One Line, No Extra Setup

Enable the remote console on a Player build with a single call:

#if DEVELOPMENT_BUILD
Zh1Zh1.CSharpConsole.RuntimeInitializer.ConsoleInitialize();
#endif

Runtime execution only depends on HybridCLR's Assembly.Load capability for IL2CPP (no additional configuration needed).

The runtime assembly is gated by DEVELOPMENT_BUILD || UNITY_EDITOR.

Port
Editor14500 (default)
Runtime15500 (default)

If a port is occupied, the service automatically advances to the next available one.

⌨ REPL Usage

Starting the REPL

The recommended way is through the Unity menu. You can also launch directly:

# Auto-discover running Unity Editors
python "Editor/ExternalTool~/console-client/csharp_repl.py"

# Connect to a specific Editor
python "Editor/ExternalTool~/console-client/csharp_repl.py" --editor --ip 127.0.0.1 --port 14500

# Connect to a Runtime Player (with Editor as compile server)
python "Editor/ExternalTool~/console-client/csharp_repl.py" \
  --mode runtime --ip 127.0.0.1 --port 15500 \
  --compile-ip 127.0.0.1 --compile-port 14500

Python 3.7+ is required. Python dependencies (requests, prompt_toolkit, Pygments) are installed automatically on first launch.

Remote Runtime — Optional Settings

When connecting to a Runtime Player via Console > RemoteC#Console, two optional settings are available to improve compilation accuracy:

SettingDescription
Runtime Dll PathDirectory containing the player's compiled assemblies. The compiler uses these DLLs instead of Editor assemblies to resolve types, ensuring the compiled code matches what the player actually has. Recommended path: Library/Bee/PlayerScriptAssemblies (populated after a player build).
Runtime Defines FileA .txt file listing preprocessor defines that match the player's build configuration, ensuring #if directives evaluate the same way as in the player. Supports one define per line or semicolon-separated (e.g. UNITY_ANDROID;IL2CPP;DEVELOPMENT_BUILD).

Both settings are persisted in EditorPrefs and only apply when Remote Is Editor is unchecked. Leave them empty to use defaults (Editor assemblies and defines).

Key Bindings

KeyAction
EnterSubmit input
Ctrl+EnterInsert newline without submitting
TabAccept completion candidate
Ctrl+RReverse history search
Ctrl+CClear input (confirm quit if empty)

Completion activates automatically as you type. The toolbar shows semantic completion status: on / off .

Built-in Commands

CommandDescription
/completion <0|1>Toggle semantic completion
/usingShow default using file path
/defineShow preprocessor defines file path
/reloadReload using / define files
/resetReset the REPL session
/clearClear the terminal
/dofile <path>Execute a local .cs file

Command Expressions

The REPL supports @-prefixed command expressions that invoke the server-side command framework directly — bypassing Roslyn compilation:

@project.scene.open(scenePath: "Assets/Scenes/SampleScene.unity", mode: "single")
@editor.status()
@session.inspect(sessionId: "session-1")

Tab completion works for both command names and argument names.

📋 Built-in Actions

50 built-in commands across 13 namespaces, covering editor control, scene manipulation, asset management, and more.

NamespaceActionDescription
gameobjectfindFind GameObjects by name, tag, or component type
createCreate a new GameObject (empty or primitive)
destroyDestroy a GameObject
getGet detailed info about a GameObject
modifyChange name, tag, layer, active state, or static flag
set_parentReparent a GameObject
duplicateDuplicate a GameObject
componentaddAdd a component to a GameObject
removeRemove a component from a GameObject
getGet serialized field data of a component
modifyModify serialized fields of a component
transformgetGet position, rotation, and scale
setSet position, rotation, and/or scale (local or world)
scenehierarchyGet the full scene hierarchy tree, optionally with component info
prefabcreateCreate a prefab asset from a scene GameObject
instantiateInstantiate a prefab into the active scene
unpackUnpack a prefab instance
materialcreateCreate a new material asset with a specified shader
getGet material properties from an asset or a Renderer
assignAssign a material to a Renderer component
screenshotscene_viewCapture the Scene View to an image file
game_viewCapture the Game View to an image file
profilerstartStart Profiler recording (optional deep profiling)
stopStop Profiler recording
statusGet current Profiler state
saveSave recorded profiler data to a .raw file
editorstatusGet editor state and play mode info
playmode.statusGet current play mode state
playmode.enterEnter play mode
playmode.exitExit play mode
menu.openExecute a menu item by path
window.openOpen an editor window by type name
console.clearClear the editor console
console.markWrite a searchable marker into the editor log and return the log file path
projectscene.listList all scenes in the project
scene.openOpen a scene by path
scene.saveSave the current scene
selection.getGet the current editor selection
selection.setSet the editor selection
asset.listList assets by type filter
asset.importImport an asset by path
asset.reimportReimport an asset by path
assetmoveMove or rename an asset
copyCopy an asset to a new path
deleteDelete one or more assets
create_folderCreate a folder in the Asset Database
sessionlistList active REPL sessions
inspectInspect a session's state
resetReset a session's compiler and executor
commandlistList all registered commands (built-in + custom)

Most actions are editor-only. session.* and command.list are available on Runtime builds as well.

🔌 Extending Commands

The command framework lets any project add custom commands without modifying the package source — declare a [CommandAction] method and the framework handles discovery, parameter binding, and routing automatically.

See the full guide: Extending Commands

📦 Requirements

DependencyVersion
Unity2022.3+ (theoretically 2019+ compatible, but untested)
Python3.7+ (on system PATH)
Windows TerminalOptional (falls back to Python directly)
  • unity-cli-plugin — Non-interactive CLI for the same HTTP service, designed for scripting and automation workflows.
  • python-prompt-toolkit — Terminal UI library powering the REPL's interactive interface.
  • HybridCLR — IL2CPP hot-reload solution enabling Assembly.Load in Runtime mode.

📄 Third-Party Notices

This package bundles Roslyn compiler assemblies and dnlib under Editor/Plugins/. See ThirdPartyNotices.md for full attribution and license details.

📜 License

Apache License 2.0