模块边界:Editor Guard 不等于运行时依赖已经移除
自动关联目录:模块边界:Editor Guard 不等于运行时依赖已经移除
核心判断:在 C++ 调用点包一层
#if WITH_EDITOR只能裁掉代码分支;只要 Runtime Module 的 Build.cs 仍依赖编辑模块、公开头仍暴露编辑类型或插件描述仍要求加载,目标产物就没有真正解耦。
一、业务冲突
编辑器需要导入、Gizmo、桌面文件对话框和工具桥;客户端、DS 与轻量运行时只需共享内容模型和玩法执行。若它们都依赖一个大 Runtime Module,任何编辑能力都会扩大编译闭包、包体和跨平台适配面,DS 还可能因不可再分发模块直接构建失败。
二、实际实现
工程已拆出 Play Runtime 与 Edit Runtime。编辑模块依赖运行模块,反向通过事件通知而非直接调用,避免 DLL 环;DS 和轻量 Target 构建编辑模块会立即失败。桌面保存、几何生成、复杂 UI、DS SDK 和平台能力按 Target/Platform 加依赖,轻量目标从链接层移除多套模块。
三、值得保留
依赖方向开始由 Build.cs 强制,而不是只靠注释。事件反转修复了真实循环依赖风险;不可再分发桌面模块只在允许的非 Shipping 桌面目标链接,也体现了 UE 模块规则与运行功能边界必须一致。
四、结构性缺陷
Play Runtime 仍承载网络、UI、压缩、资源、物理、桌面集成和多类平台适配,私有依赖面很大。部分能力由 Target 名字符串决定,公共宏甚至影响对外类型布局;测试模块直接加入另一个模块的 Private include path,也会侵蚀边界。宏关掉实现,不代表头文件、反射注册和资产引用都消失。
五、目标设计
ContentCore <- 纯数据、Schema、身份、无 UE 编辑依赖
GameplayRuntime <- Client/DS 共享执行契约
PresentationAdapter <- UMG、音频、渲染,仅表现目标
AuthoringAdapter <- Editor、Gizmo、桌面 I/O
PlatformAdapter <- 按 Target 注入网络、文件、SDK模块通过窄接口和事件交换稳定值对象,不共享 Private 头。Target Profile 注入 Capability Provider;Build.cs 只根据结构化能力加依赖。架构测试读取 UBT 依赖图、UHT Manifest、链接 Map 和 Asset Registry,验证禁入边,而非搜索宏文本。
六、取舍与验证
拆模块会增加接口、桥接和迁移成本,过细也会拖慢 UE 构建。优先切断“目标不支持且依赖昂贵”的边,并为每次提取保留编译与运行测试。完成标准是目标链接闭包中不存在禁入模块,禁用插件后仍能启动关键场景,而不是源码里看见了一个 Guard。