CSharp Console
August 23, 2026 · View on GitHub
CSharp Console
Unity 交互式 C# REPL — 基于 Roslyn
在 Unity Editor 和 Runtime 中即时执行 C# 代码 — 无需等待编译,无需样板代码,
完整访问项目运行时状态。Editor 零配置开箱即用,Runtime 搭配 HybridCLR 即刻运行。
功能特性 · 安装 · 快速开始 · REPL 使用 · 扩展命令
English | 中文
✦ 功能特性
核心能力
| 特性 | 说明 | |
|---|---|---|
| >_ | 交互式 REPL | 基于 Roslyn 的脚本提交,会话状态持久保持 — 变量、using 指令、类型在多次执行间存活 |
| # | Top-level 语法 | 直接写语句,不需要 class、Main、任何样板代码 |
| @ | 命令框架 | 可扩展的 [CommandAction] 命令,自动 JSON 参数绑定(位置参数 & 命名参数),/batch 端点支持多命令批量执行 |
| Tab | 语义补全 | 来自 Roslyn 的实时成员、命名空间、类型补全 |
| 🔓 | 私有成员访问 | 编译阶段绕过 private / protected / internal 访问修饰符,深度检查对象 |
| ⏸ | 暂停态调试 | Editor 暂停于播放模式时仍可提交代码 — 检查暂停瞬间的瞬时状态,调试不丢现场 |
| 📡 | 远程执行 | Editor 编译,Player 执行(IL2CPP 通过 HybridCLR) |
效果展示
实时主题预览 — 用 ↑ / ↓ 浏览候选项
/theme
模糊语义补全 — 只输入关键字符
GameObject.fnd → GameObject.Find
私有成员访问 — 接受补全前即可看到访问级别
cam.mid → cam.m_InstanceID
跨提交状态 — 在后续表达式复用实时 Unity 对象
var m = cam.transform.localToWorldMatrix
m.mp34 → m.MultiplyPoint3x4
命令表达式 — 直接检查 Editor 状态
@editor.status()
⚙ 安装
通过 Packages/manifest.json 添加:
{
"dependencies": {
"com.zh1zh1.csharpconsole": "https://github.com/niqibiao/unity-csharpconsole.git"
}
}
或作为本地包引用:
{
"dependencies": {
"com.zh1zh1.csharpconsole": "file:../com.zh1zh1.csharpconsole"
}
}
注意: 两个 asmdef 均设置了
autoReferenced: false。如需引用本包,请在 asmdef 中显式添加Zh1Zh1.CSharpConsole.Runtime(或.Editor)。
▶ 快速开始
Editor — 零配置
导入包即可使用。 Editor 侧 HTTP 服务通过 [InitializeOnLoadMethod] 自动启动 — 无需初始化代码,无需调整设置,无需手动配置。从 Unity 菜单打开 REPL:
| 菜单项 | 连接目标 |
|---|---|
| Console > C#Console | 本地 Editor |
| Console > RemoteC#Console | 远程 Editor / Player |
Runtime — 一行代码,无需额外配置
在 Player 构建中启用远程控制台,只需一行调用:
#if DEVELOPMENT_BUILD
Zh1Zh1.CSharpConsole.RuntimeInitializer.ConsoleInitialize();
#endif
Runtime 执行仅依赖 HybridCLR 的 Assembly.Load 能力实现 IL2CPP 下的程序集加载(无需任何额外配置)。
Runtime 程序集受
DEVELOPMENT_BUILD || UNITY_EDITOR条件编译约束
| 端口 | |
|---|---|
| Editor | 14500(默认) |
| Runtime | 15500(默认) |
端口被占用时自动递增到下一个可用端口。
Warning
服务默认监听所有网卡且不做鉴权,这是面向可信局域网的设计:支持连到同事机器上的 Editor 或真机构建是功能的一部分。任何能访问该端口的人都可以在你的 Editor 里执行 C# —— 请勿把端口暴露到不可信网络。
⌨ REPL 使用
启动
推荐通过 Unity 菜单启动,也可以直接运行:
# 自动发现运行中的 Unity Editor
python "Editor/ExternalTool~/console-client/csharp_repl.py"
# 连接指定 Editor
python "Editor/ExternalTool~/console-client/csharp_repl.py" --editor --ip 127.0.0.1 --port 14500
# 连接 Runtime Player(Editor 作为编译服务器)
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+。Python 依赖(requests、prompt_toolkit、Pygments)在首次启动时自动安装。
远程 Runtime — 可选设置
通过 Console > RemoteC#Console 连接 Runtime Player 时,有两个可选设置可以提高编译准确性:
| 设置 | 说明 |
|---|---|
| Runtime Dll Path | Player 编译后的程序集目录。编译器使用这些 DLL 替代 Editor 程序集来解析类型,确保编译结果与 Player 实际运行环境一致。推荐路径:Library/Bee/PlayerScriptAssemblies(执行 Player 构建后生成)。 |
| Runtime Defines File | .txt 文件,列出与 Player 构建配置一致的预处理器宏定义,确保 #if 指令编译时与 Player 端求值结果相同。支持每行一个宏定义或分号分隔(如 UNITY_ANDROID;IL2CPP;DEVELOPMENT_BUILD)。 |
两项设置持久化在 EditorPrefs 中,仅在 Remote Is Editor 未勾选时生效。留空则使用默认值(Editor 程序集和宏定义)。
快捷键
| 按键 | 操作 |
|---|---|
Enter | 提交输入 |
Ctrl+Enter | 插入换行,不提交 |
Tab | 接受补全候选 |
Ctrl+R | 反向历史搜索 |
Ctrl+C | 复制选中内容;未选中时清空输入(输入为空时确认退出) |
输入时自动触发补全。工具栏显示语义补全状态:开启 ● / 关闭 ○。
内置命令
| 命令 | 说明 |
|---|---|
/completion <0|1> | 切换语义补全 |
/theme [名称] | 列出或切换代码高亮主题 |
/using | 显示默认 using 文件路径 |
/define | 显示预处理宏文件路径 |
/reload | 重新加载 using / define 文件 |
/reset | 重置 REPL 会话 |
/clear | 清空终端 |
/dofile <path> | 执行本地 .cs 文件 |
命令表达式
REPL 支持 @ 前缀的命令表达式,直接调用服务端命令框架 — 不经过 Roslyn 编译:
@project.scene.open(scenePath: "Assets/Scenes/SampleScene.unity", mode: "single")
@editor.status()
@session.inspect(sessionId: "session-1")
Tab 补全支持命令名和参数名。
📋 内置 Action
15 个命名空间,62 个内置命令,覆盖编辑器控制、场景操作、资产管理等常见场景。
| 命名空间 | Action | 说明 |
|---|---|---|
| gameobject | find | 按名称、标签或组件类型查找 GameObject |
create | 创建新 GameObject(空对象或基本体) | |
destroy | 销毁 GameObject | |
get | 获取 GameObject、Transform、组件与静态状态详情 | |
modify | 修改名称、标签、层级、激活状态或静态标记 | |
set_parent | 更改 GameObject 的父级 | |
duplicate | 复制 GameObject | |
| component | add | 为 GameObject 添加组件 |
remove | 从 GameObject 移除组件 | |
get | 获取组件的序列化字段数据 | |
modify | 修改组件的序列化字段 | |
| transform | set | 设置位置、旋转和/或缩放(本地或世界坐标) |
| scene | hierarchy | 获取完整场景层级树,可选包含组件信息 |
| prefab | create | 从场景 GameObject 创建 Prefab 资产 |
instantiate | 将 Prefab 实例化到当前场景 | |
unpack | 解包 Prefab 实例 | |
asset_hierarchy | 获取 Prefab 资产的层级树 | |
asset_get | 获取 Prefab 资产中某个 GameObject 的详情 | |
asset_get_component | 获取 Prefab 资产中某个组件的序列化属性 | |
asset_modify_component | 修改 Prefab 资产中某个组件的序列化字段 | |
asset_add_component | 为 Prefab 资产中的 GameObject 添加组件 | |
asset_remove_component | 从 Prefab 资产中的 GameObject 移除组件 | |
asset_modify_gameobject | 修改 Prefab 资产中某个 GameObject 的属性 | |
asset_add_gameobject | 向 Prefab 资产添加子 GameObject | |
asset_remove_gameobject | 从 Prefab 资产移除子 GameObject | |
| material | create | 使用指定 Shader 创建新材质资产 |
get | 从资产或 Renderer 获取材质属性 | |
assign | 将材质分配给 Renderer 组件 | |
| scriptableobject | create | 按类型创建 ScriptableObject 资产 |
get | 获取 ScriptableObject 资产的序列化字段数据 | |
modify | 修改 ScriptableObject 资产的序列化字段 | |
| screenshot | scene_view | 截取 Scene View 到图片文件 |
game_view | 截取 Game View 到图片文件 | |
| profiler | start | 开始 Profiler 录制(可选深度分析) |
stop | 停止 Profiler 录制 | |
status | 获取当前 Profiler 状态 | |
save | 将录制的性能数据保存为 .raw 文件 | |
| editor | status | 获取编辑器、播放模式与切换状态 |
playmode.enter | 进入播放模式 | |
playmode.exit | 退出播放模式 | |
console.clear | 清空编辑器控制台 | |
console.mark | 向编辑器日志写入可搜索标记并返回日志文件路径 | |
test.run | 启动 Unity Test Framework 测试(EditMode 或 PlayMode) | |
test.status | 获取最近一次测试运行的状态与结果 | |
| project | scene.list | 列出项目中所有场景 |
scene.open | 通过路径打开场景 | |
scene.save | 保存当前场景 | |
selection.get | 获取当前编辑器选中对象 | |
selection.set | 设置编辑器选中对象 | |
asset.list | 按类型筛选列出资产 | |
asset.import | 按路径导入资产 | |
asset.reimport | 按路径重新导入资产 | |
| asset | move | 移动或重命名资产 |
copy | 复制资产到新路径 | |
delete | 删除一个或多个资产 | |
create_folder | 在 Asset Database 中创建文件夹 | |
| session | list | 列出活跃的 REPL 会话 |
inspect | 检查会话状态 | |
reset | 重置会话的编译器和执行器 | |
| command | list | 列出所有已注册命令(内置 + 自定义) |
registry.snapshot | 获取命令注册表快照 | |
| runtime | info | 返回应答进程的设备信息与常用文件路径 |
39 个 Action 需要 Editor,发到 Runtime 构建会明确报错。其余 23 个在 Runtime 构建中同样应答:
runtime/info、scene/hierarchy、gameobject/*、transform/set、component/*、screenshot/game_view、profiler/start|stop|status、session/*、command/*。Runtime 没有 Undo 栈,在那里做的修改无法撤销;component/get|modify在 Runtime 只覆盖工程自己声明的组件——内置组件的状态存在原生属性而非序列化字段里。
prefab/asset_*直接编辑磁盘上的资产,无需打开场景。其子物体通过asset_hierarchy返回的身份选择器(gid:<guid>:<localFileId>)定位,而非名称路径。
editor/test.*需要消费项目安装com.unity.test-framework;未安装时命令仍在注册表中,但会返回说明性错误。
🔌 扩展命令
命令框架允许任何项目在不修改本包源码的情况下添加自定义命令 — 声明一个 [CommandAction] 方法,框架自动处理发现、参数绑定和路由。
完整指南:扩展命令
📦 环境要求
| 依赖 | 版本 |
|---|---|
| Unity | 2022.3+ |
| Python | 3.7+(系统 PATH 可访问) |
| Windows Terminal | 可选(不可用时回退到直接启动 Python) |
🔗 相关项目
- unity-cli-plugin — 非交互式 CLI,连接同一 HTTP 服务,面向脚本和自动化场景。
- python-prompt-toolkit — REPL 交互界面所依赖的 Python 终端 UI 库。
- HybridCLR — IL2CPP 热更新方案,Runtime 模式下的程序集加载依赖此项目。
📄 第三方声明
本包在 Editor/Plugins/ 下捆绑了 Roslyn 编译器程序集和 dnlib。完整归属和许可信息见 ThirdPartyNotices.md。