
ET UnityBridge 深度解析命令行桥接 Unity Editor 的架构、协议与 AI 自动化实操指南【免费下载链接】ETUnity3D Client And C# Server Framework项目地址: https://gitcode.com/GitHub_Trending/et/ET导读cn.etetet.unitybridge是 ET 框架中的Unity 本地文件桥接包它通过一个纯命令行程序ET.UnityBridge.dll与 Unity Editor 内的文件宿主进程通信让 AI Agent 或脚本以dotnet命令直接驱动 Unity——查询编译状态、进入/退出 PlayMode、操作资源、场景、GameObject、Inspector、Prefab甚至截图和跑 Editor 测试。读完本文你将掌握该桥接包的目录结构与通信协议、CLI 全部传输参数与命令发现方法、deferred 长时命令的底层机制以及一套可直接上手的 AI 操作 Unity 的最小工作流。包定位与三层结构根据 AGENTS.md 的概述本包围绕“Unity 本地文件桥接”提供三部分能力组成职责DotNet~纯命令行程序ET.UnityBridge对应工程 ET.UnityBridge.csprojScripts/EditorUnity Editor 文件宿主汇入ET.Editor负责在编辑器内轮询请求、分发执行、写回响应Scripts/Model/Share桥接命令、错误码与共享文件协议两端共用的数据结构对应的核心目录速览引自原文档路径说明DotNet~ET.UnityBridge.csproj与命令行入口Scripts/EditorUnity Editor 宿主、处理器与分发逻辑Scripts/Model/Share桥接命令、错误码、路径与文件存储协议这种“命令行客户端 Editor 宿主 共享协议”的三层设计使桥接完全不依赖网络端口或 HTTP 服务所有数据通过本地磁盘文件交换Unity 侧无需开启任何服务器监听天然适配编辑器安全沙箱。通信原理本地文件存储协议根目录解析优先级桥接两端通过同一个根目录交换文件路径解析逻辑在 UnityBridgeStorage.cs 的UnityBridgePathHelper.ResolveRoot中实现优先级如下显式传入的--root 路径环境变量ET_UNITY_BRIDGE_ROOT默认值Temp/UnityBridge相对项目根目录。CLI 端在 Program.cs 中调用UnityBridgePathHelper.ResolveRoot(root)完成解析Unity 侧 UnityBridgeEditorHost.cs 在静态构造时用同样的规则缓存根目录。两端必须解析到同一目录否则就会出现wait unity bridge response timeout。目录布局与文件流转UnityBridgeFileStore.EnsureDirectories见 UnityBridgeStorage.cs会创建以下子目录目录用途requests/CLI 写入的待处理请求{rpcId}.jsonprocessing/Editor 取出后正在处理的请求responses/Editor 写回的响应{rpcId}.jsonCLI 读取后删除deadletter/无法解析的请求被移入的“死信”区state/内部状态含pending-command.jsondeferred 命令与idempotency/幂等缓存一次完整请求的流转为CLI 通过UnityBridgeFileStore.WriteRequest原子写入requests/{rpcId}.jsonUnityBridgeStorage.cs→ Editor 轮询到后用File.Move移入processing/保证单次只被一个进程处理→ 执行完成后WriteResponse写回responses/{rpcId}.json并删除 processing 文件 → CLI 读到响应即删除该响应文件。所有写入都走“临时文件 替换”的原子写路径WriteTextAtomic避免半写状态被另一端读到。RPC 信封CLI 与 Editor 交换的不只是命令本身而是一个信封对象UnityBridgeRequestEnvelope见 UnityBridgeCommands.cs包含四个字段RpcId本次调用的唯一标识由 CLI 用进程 ID、随机数与时间戳异或生成Program.csIdempotencyKey幂等键配合响应缓存实现“同一命令重复发送只执行一次”TimeoutMs超时上限0 表示不设超时CommandJson真正的命令 JSON以_t字段标注命令类型。CLI 使用入门入口与最小流程CLI 入口固定为dotnet ./Bin/ET.UnityBridge.dll如果Bin/ET.UnityBridge.dll尚不存在需要先用et-build编译确认工具已生成。不带参数直接运行会输出unity bridge command is empty并以退出码 2 结束见 Program.cs。最小可用命令是Ping用于探测宿主是否在线dotnet ./Bin/ET.UnityBridge.dll {_t:Ping}需要命令列表或详细状态时使用HostStatedotnet ./Bin/ET.UnityBridge.dll {_t:HostState}传输参数CLI 支持四个传输参数在 Program.cs 中以TransportOptions定义参数作用默认值--root 路径显式指定桥接根目录环境变量ET_UNITY_BRIDGE_ROOT否则Temp/UnityBridge--waitMs 毫秒客户端等待最终响应的时间15000--timeoutMs 毫秒单条命令的服务端超时上限写入信封0不设限服务端另有分命令默认值--idempotencyKey 字符串幂等键用于去重与结果缓存自动生成 GUIDN 格式组合示例dotnet ./Bin/ET.UnityBridge.dll {_t:HostState} --root Temp/UnityBridge --waitMs 15000 --timeoutMs 10000 --idempotencyKey host-state-check等待与自动延长机制SendRequestProgram.cs在写入请求后以 100ms 间隔轮询响应文件直到超过waitMs截止时间。关键细节当未显式指定--waitMs时如果检测到state/pending-command.json中存在与当前 RpcId 匹配的 deferred 命令CLI 会自动把等待期限延长到DefaultDeferredWaitMs185 秒。这意味着Compile、EnterPlay这类耗时长命令默认最多能等到 185 秒无需手工加大--waitMs。命令协议与常用命令协议定义位置全部命令与响应结构定义在 Proto 目录下UnityBridge_C_11100.proto状态类命令、资源类命令、场景/选择集/测试/截图/GameView 命令以及BridgeVector2/3、BridgeQuaternion、BridgeTransformInfo、BridgeObjectInfo、BridgeAssetInfo等共享消息结构UnityBridge_C_11400.protoGameObject/Transform/菜单/Prefab/Inspector/Undo-Redo/BatchExecute 命令。六个核心状态命令命令作用响应特有字段Ping连通性探测返回编译/PlayMode/CodeMode/Unity 版本Time、IsCompiling、IsPlaying、IsPlayingOrWillChangePlaymode、CodeMode、UnityVersionHostState额外返回可用命令清单AvailableCommandsCompile触发一次脚本编译DurationMsRefresh刷新资源数据库—RegenProject重新生成 VS/Rider 工程文件—EnterPlay/ExitPlay进入 / 退出 PlayModeIsPlayingReload热重载要求已在 PlayMode—命令发现不要手工背诵全部命令名。两条路径运行时用HostState的AvailableCommands字段拿当前宿主支持的完整命令列表静态用rg在 Proto 目录检索命令消息rg -n ^message .*Request|^message (Ping|HostState|Compile|Refresh|RegenProject|EnterPlay|ExitPlay|Reload)\b ./Packages/cn.etetet.unitybridge/Proto需要行为细节时再按需打开对应的单个 handlerScripts/Editor/Share/下每个命令一个UnityBridgeXxxHandler.cs不要整包读取。推荐执行顺序skill 文档给出的状态变化类命令有严格的先后关系目标顺序编译HostState→Compile刷新HostState→Refresh重建工程文件HostState→RegenProject进入 PlayMode确认IsCompiling false且IsPlayingOrWillChangePlaymode false→EnterPlay热重载确认IsPlaying true→Reload退出 PlayModeHostState→ExitPlay状态检查Ping 与 HostState 解读Ping是每次操作前的必做动作一个典型响应对照 UnityBridge_C_11100.proto{_t:PingResponse,RpcId:1,Error:0,Time:1715000000000, IsCompiling:false,IsPlaying:false,IsPlayingOrWillChangePlaymode:false, CodeMode:Code,UnityVersion:2022.3.0f1}各字段含义Error0 表示成功非 0 表示失败IsCompilingUnity 是否正在编译脚本IsPlaying当前是否处于 PlayModeIsPlayingOrWillChangePlaymode是否处于 PlayMode 或正在切换 PlayModeEnterPlay的前置检查依据CodeMode当前代码模式从Resources/GlobalConfig的CodeMode字段反射读取见 UnityBridgeEditorStatus.csUnityVersion编辑器版本。HostState在此基础上额外携带AvailableCommands适合在任务开始前一次性确认宿主能力与命令拼写。事件驱动的 Unity Editor 宿主轮询循环Editor 侧宿主UnityBridgeEditorHost使用[InitializeOnLoad]在编辑器启动时挂载到EditorApplication.update以0.2 秒为周期轮询UnityBridgeEditorHost.cs先尝试UnityBridgeDeferredRuntime.TryPump泵送已挂起的 deferred 命令若无挂起命令且距上次轮询超过 0.2 秒则取一条新请求ProcessOneRequestAsync中先TryTakeNextRequest把requests/中排序后的第一个文件原子移动到processing/再执行HandleRequest执行结果若为普通响应写回responses/并删除 processing 文件若为 deferred 响应则交由 Deferred 运行时接管。服务端超时HandleRequest会根据命令类型给出服务端侧默认超时UnityBridgeEditorHost.cs命令服务端默认超时Compile180000 msRefresh/RegenProject/EnterPlay/ExitPlay60000 ms其他命令10000 ms若请求在processing/中停留超过TimeoutMs宿主直接返回unity bridge request timeout。幂等缓存每次请求携带IdempotencyKey宿主在执行成功后把响应写入state/idempotency/{sha256(key)}.json后续相同幂等键的请求直接命中缓存返回并替换为新 RpcId避免EnterPlay、Compile这类命令被重复执行见 UnityBridgeEditorHost.cs 与 UnityBridgeStorage.cs。命令分发与 Handler 体系Dispatcher 注册机制UnityBridgeEditorDispatcher在静态构造时通过TypeCache.GetTypesDerivedFromIUnityBridgeHandler()反射收集所有 handler 实现校验每个 handler 的RequestType/ResponseType合法且无重复后建立“请求类型 → handler”映射UnityBridgeEditorDispatcher.cs。扩展桥接命令只需新增一个继承AUnityBridgeHandlerTRequest, TResponse的 handler 类无需修改分发器。命令 JSON 的_t判别Dispatcher 的TryNormalizeCommandJson解析规则UnityBridgeEditorDispatcher.cs必须包含_t字段支持字符串或 BSON 多态数组取最后一个非空值旧的CommandType/Payload封装格式已废弃会直接报错提示改用_t命令名可以是短名如Ping或全名ET.Ping分发器自动归一化为全名后反序列化。错误码定义错误码集中在 ErrorCode.cs常量值基于PackageType.UnityBridge推导含义Success0成功InvalidCommandLine200000000 包号×1000 1命令行/命令 JSON 非法Timeout200000000 包号×1000 2等待超时NotInPlayMode200000000 包号×1000 3不在 PlayModeExitPlay/Reload前置不满足AlreadyInPlayMode200000000 包号×1000 4已处于 PlayMode重复EnterPlayCompiling200000000 包号×1000 5Unity 正在编译暂不能开始新的延迟命令HandlerFail100000000 包号×1000 1handler 执行失败CLI 侧读到Error 0时以退出码 0 结束否则以退出码 1 结束Program.cs并原样打印响应 JSON 供调用方解读。Deferred 命令长时操作的实现原理Compile、Refresh、EnterPlay、AssetImportRequest等命令会改变 Unity 编辑器状态或耗时较长被设计为deferred延迟命令。其机制分为两层Handler 层AUnityBridgeDeferredHandlerAUnityBridgeDeferredHandlerTRequest, TResponseAUnityBridgeDeferredHandler.cs在首次Handle时调用UnityBridgeDeferredRuntime.TryCreatePendingCurrent把命令快照含 RpcId、幂等键、超时、开始时间写入state/pending-command.json以UnityBridgeDeferredContext.CreateStart()执行一次Run此时 handler 内通过deferred.StartedTResponse()主动抛出UnityBridgeDeferredStartedException分发器捕获该异常后返回UnityBridgeDeferredResponseUnityBridgeCommands.cs宿主识别IsDeferredResponse后不写响应直接返回等待后续泵送。运行时层轮询泵送与恢复UnityBridgeDeferredRuntime.TryPumpUnityBridgeDeferredRuntime.cs在每个 Editor update 帧先于普通请求执行读到pending-command.json后反序列化命令、查找 handler调用deferredHandler.Deferred(command, startedAt)handler 内部用deferred.NotReadyTResponse()抛出UnityBridgeDeferredNotReadyException表示“还没就绪”运行时收到null响应则什么都不做下一帧再试条件满足如编译完成、PlayMode 切换完成后 handler 返回正式响应运行时通过Complete写缓存、写响应、清理 processing 与 pending 状态文件若now - StartedAt TimeoutMs直接以Timeout错误码完成。这就是为什么 skill 文档反复强调deferred 命令必须等待最终响应不能看到请求被接收就结束。CLI 端的 185 秒自动延长等待正是为此设计。AI 操作 Unity 的任务路由来自 et-unitybridge-ai-ops.md 的任务路由表是 AI 使用桥接包的最高频场景索引目标优先命令族常见前置状态 / 连通性Ping、HostState、EditorGetStateRequest无编译 / 刷新Compile、Refresh、RegenProject、AssetRefreshRequest、AssetImportRequestIsCompiling falsePlayMode / 热重载EnterPlay、ExitPlay、Reload、EditorPauseRequest检查IsPlaying/IsPlayingOrWillChangePlaymode资源AssetSearchRequest、AssetFindRequest、AssetLoadRequest、AssetReadTextRequest、AssetGetPathRequest先限定 filter/path/count场景SceneGetHierarchyRequest、SceneGetActiveRequest、SceneLoadRequest、SceneSaveRequest、SceneNewRequest写操作前确认当前场景选择集SelectionGetRequest、SelectionSetRequest、SelectionAddRequest、SelectionRemoveRequest、SelectionClearRequest先读当前 selection对象 / TransformGameObject*Request、Transform*Request先Find/GetInfo/GetInspectorInspectorGet*Request、InspectorSet*Request、InspectorAddComponentRequest、InspectorRemoveComponentRequest先读组件和属性名PrefabPrefabInstantiateRequest、PrefabSaveRequest、PrefabApplyRequest、PrefabGet*Request、PrefabUnpackRequest先确认 asset path / instance截图 / GameViewScreenshotCaptureRequest、GameView*Request先读分辨率测试UnityTestRunRequest用精确正则批量BatchExecuteRequest先单步验证核心操作模式读状态先读后写dotnet ./Bin/ET.UnityBridge.dll {_t:HostState}只总结关键字段Error、Message、IsCompiling、IsPlaying、IsPlayingOrWillChangePlaymode、所需命令是否存在。执行 deferred 命令dotnet ./Bin/ET.UnityBridge.dll {_t:Refresh}若返回unity is compiling先轮询Ping直到IsCompiling false再重试。查资源小范围限定dotnet ./Bin/ET.UnityBridge.dll {_t:AssetFindRequest,Filter:t:Prefab,MaxResults:10}读场景层级dotnet ./Bin/ET.UnityBridge.dll {_t:SceneGetHierarchyRequest,Depth:2,IncludeInactive:false}写操作后用GameObjectGetInfoRequest或TransformGetRequest验证结果不能只相信命令返回成功。读 Inspectordotnet ./Bin/ET.UnityBridge.dll {_t:InspectorGetComponentsRequest,Path:HierarchyPath}先读组件列表和属性名再执行 set 命令不要猜测SerializedProperty路径。跑 Editor 测试精确正则避免全量dotnet ./Bin/ET.UnityBridge.dll {_t:UnityTestRunRequest,Name:^Unitybridge_DeferredHandlerRunContext_Test$}判定标准Error 0、Matched 0、Failed 0。输出解读与常见错误响应通用规则Error 0表示成功非 0 表示失败需结合Message判断原因CompileResponse额外包含DurationMs编译耗时EnterPlayResponse/ExitPlayResponse额外包含IsPlayingPingResponse/HostStateResponse额外包含Time/IsCompiling/IsPlaying/IsPlayingOrWillChangePlaymode/CodeMode/UnityVersion/AvailableCommands。常见错误排查表错误信息含义与处理wait unity bridge response timeoutUnity 未打开、项目未加载完、桥接根目录不一致或 Editor 未处理请求先检查ET_UNITY_BRIDGE_ROOT/--root是否两端一致unity is compilingUnity 正在编译暂时不能开始新的延迟命令轮询Ping等待编译结束unity already in playmode or changing playmode已处于 PlayMode不能重复执行EnterPlayunity not in playmodeExitPlay/Reload的前置条件不满足需先EnterPlayhandler is missing命令名拼写错误或宿主版本不支持先用HostState确认AvailableCommandsexecute menu item failed菜单路径不存在或 Unity 当前状态不允许执行省 Token 操作规范skill 文档明确要求 AI 端遵循“最小读取”原则不要完整读取所有 proto、handler 或AvailableCommands先用HostState或rg发现命令名再只打开相关 proto 小片段和对应 handler先执行最小读命令确认目标再做写操作批量操作前先验证 1 个样本不要把完整 JSON 响应贴给用户只总结Error、Message和关键字段优先 UnityBridge 命令而非 GUI 点击除非命令缺失或用户明确要求。测试与验证本包在 Scripts/Editor/Test 目录提供了覆盖各命令族协议消息与 handler 行为的 Editor 测试例如Unitybridge_DeferredHandlerRunContext_Test.csdeferred 上下文、Unitybridge_GameViewSetResolutionHandlerInvalidSize_Test.cs非法参数、Unitybridge_ExitPlayModeHandlerNotInPlayModeError_Test.cs错误前置条件等可作为命令行为与错误码语义的权威参考。测试辅助类 UnityBridgeHandlerTestSupport.cs 与 UnityBridgeProtocolTestSupport.cs 用于构造请求与断言响应。更多参考skill 入口文档skills/et-unitybridge/SKILL.mdCLI 传输、等待、返回值解读references/et-unitybridge-cli.mdAI 操作 Unity 的任务路由与操作模式references/et-unitybridge-ai-ops.md命令行入口实现DotNet~/Program.cs协议定义Proto/UnityBridge_C_11100.proto、Proto/UnityBridge_C_11400.proto掌握以上内容后你即可用一句dotnet ./Bin/ET.UnityBridge.dll {_t:Ping}建立与 Unity Editor 的桥接并沿任务路由表逐步完成从状态查询到资源、场景、PlayMode、测试的完整 AI 自动化操作闭环。【免费下载链接】ETUnity3D Client And C# Server Framework项目地址: https://gitcode.com/GitHub_Trending/et/ET创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考