Files
XCEngine/docs/plan/毕设/初稿/第六章.md

110 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第六章 编辑器与引擎工作流设计与实现
上一章已经围绕渲染引擎运行时的核心模块展开分析,说明了各个模块的实现方式。在此基础上,本章进一步转向引擎的可视化界面与工作流部分,重点说明当前项目中的编辑器如何围绕场景编辑、资源浏览、参数调整、脚本运行和调试输出等功能组织起来。对于本课题而言,编辑器是连接资源系统、场景系统、渲染系统和脚本系统的直接入口,也是展示整个系统功能的重要部分。
## 6.1 编辑器在引擎中的定位
当前项目中的编辑器由 `Application``EditorLayer``EditorWorkspace` 以及各类面板共同构成,其初始化过程直接建立在现有引擎能力之上。编辑器启动后,会依次完成窗口渲染器初始化、项目根目录设置、`ResourceManager` 与脚本运行时初始化、ImGui 后端桥接以及视口离屏渲染资源接管,随后进入逐帧更新与绘制阶段。编辑器是直接复用资源系统、渲染链路、场景数据和脚本运行时能力的可视化工作界面,它承担的核心任务包括场景编辑、资源管理、渲染结果验证以及脚本与调试支撑,并通过 `Scene``Game``Hierarchy``Inspector``Project``Console` 等主要面板组织这些工作。
编辑器与运行时之间的关系并不是简单的界面展示关系,而是围绕统一上下文形成了完整闭环。`EditorContext` 负责组织事件总线、选择管理器、场景管理器、项目管理器、撤销管理器和视口宿主服务,使不同面板之间的数据与事件能够保持联动;`EditorWorkspace` 负责在运行阶段组织菜单栏、停靠布局和各类面板的更新与绘制;`PlaySessionController` 则负责连接编辑态与运行态,在进入播放模式前保存场景快照、停止播放后恢复快照。这样一来,编辑器既能够把 `Game` 视口中的脚本逻辑和运行时场景更新真实执行出来,又能够在退出运行后回到稳定的编辑状态,因此它构成了当前渲染引擎工作流中的核心组织层。
## 6.2 编辑器界面总体布局设计
### 6.2.1 主要界面面板组成
从当前实现来看,编辑器界面主要由顶部菜单栏与运行控制区、左侧层级面板、中部双视口区域、右侧属性检查面板以及底部控制台和项目资源面板构成。各部分职责划分明确:`MenuBar` 负责主菜单与运行模式控制,`HierarchyPanel` 用于展示当前场景对象树,`SceneViewPanel``GameViewPanel` 分别承担编辑视图与运行视图显示任务,`InspectorPanel` 负责组件和资源属性编辑,`ProjectPanel` 负责项目目录与资源浏览,`ConsolePanel` 则承担日志查看与调试辅助功能。
【插图: 编辑器界面整体截图】
这种布局与当前项目已经具备的功能模块一一对应。由于本项目已经具备场景系统、组件系统、材质系统、脚本系统和基础运行模式切换能力,因此编辑器界面也自然围绕这些能力组织。用户在编辑器中完成的操作路径,基本可以概括为“在 `Project` 中选择资源,在 `Hierarchy` 中定位对象,在 `Inspector` 中调整参数,在 `Scene` 中观察编辑结果,在 `Game` 中验证运行结果,并通过 `Console` 反馈调试信息”。
### 6.2.2 停靠布局与空间组织方式
编辑器界面的整体停靠布局由 `DockLayoutController` 统一管理。当前默认布局中,左侧区域停靠 `Hierarchy`,中部区域停靠 `Scene``Game` 两个标签页,右侧区域停靠 `Inspector`,底部区域停靠 `Console``Project`。这一布局与当前工程任务之间具有较强的一致性:对象结构查看放在左侧,核心视口放在中央,参数编辑放在右侧,资源与调试信息放在底部,符合渲染引擎编辑器的基本操作习惯,也便于在论文中按照“对象编辑 - 视口验证 - 资源管理 - 调试反馈”的路径说明工作流。
在界面上方,`MenuBar` 除了主菜单外,还单独绘制了运行工具条。该工具条提供播放、暂停和单步执行三个核心按钮,并直接与当前运行模式状态联动。这样一来,场景编辑、运行控制和视口验证被组织在同一工作界面中,用户无需在不同程序之间切换即可完成从编辑到验证的全过程。
### 6.2.3 面板之间的联动关系
编辑器界面的价值不仅在于布局清晰,更在于各面板之间形成了稳定的数据联动。`HierarchyPanel` 中的选择结果会同步到选择管理器,随后 `InspectorPanel` 根据当前选中对象展示组件信息;`ProjectPanel` 中选中的材质资源则会切换 Inspector 的检查对象类型,使其进入材质资源编辑模式;`SceneViewPanel` 中通过拾取选中的对象同样会反馈到层级面板和 Inspector`ConsolePanel` 中的日志信息又能够反向服务于当前脚本和运行调试。
因此,界面布局设计本质上也是工作流设计。通过统一的编辑上下文,各面板既保持了职责分工,又避免了信息孤立,使编辑器能够围绕当前引擎形成完整的操作闭环。
## 6.3 Scene 与 Game 视口实现
### 6.3.1 视口离屏渲染接入方式
当前编辑器中的视口通过离屏渲染方式接入。`ViewportPanelContent` 在绘制 `Scene``Game` 面板时,会向 `IViewportHostService` 发起 `RequestViewport` 请求,请求中包含视口类型和当前窗口可用尺寸。`ViewportHostService` 接收到请求后,会根据目标尺寸检查或创建对应的离屏颜色缓冲、深度缓冲以及相关资源视图,并在后续渲染阶段返回可供 ImGui 显示的纹理句柄。
这种设计带来的直接好处是,编辑器视口与主窗口交换链输出相互分离。视口可以根据面板尺寸独立变化,也可以附加对象 ID 缓冲、叠加层和调试通道,而不必改变主窗口渲染流程。对于需要同时存在编辑视图和运行视图的渲染引擎而言,这种离屏接入方式具有较好的工程适配性。
### 6.3.2 Scene 视口的组织方式
`Scene` 视口服务于编辑过程,因此它采用独立于运行时场景相机的编辑器相机。`ViewportHostService` 内部维护了专用的 `SceneViewCameraState`,其中包含编辑器相机对象、相机组件和相机控制器。用户在 `SceneViewPanel` 中进行观察、缩放、平移、环绕和聚焦操作时,面板会构造 `SceneViewportInput` 并提交给 `ViewportHostService`,由后者更新场景视口相机状态。
在渲染阶段,`Scene` 视口会先围绕当前编辑器相机生成渲染请求,再结合对象选择结果和叠加信息构造额外的编辑器渲染计划。当前实现中,`Scene` 视口已经支持对象 ID 读回拾取、选中轮廓高亮、网格显示、变换 Gizmo、方向指示器以及编辑器叠加层缓存等能力。这说明 `Scene` 视口是一个建立在引擎渲染链路之上的可交互编辑视图。
### 6.3.3 Game 视口的组织方式
`Scene` 视口不同,`Game` 视口主要用于展示运行时场景输出结果。它不使用独立的编辑器相机,而是直接依赖当前场景中的可用相机,由 `SceneRenderer` 使用正常的运行时渲染流程完成输出。若场景中不存在可用相机,则 `Game` 视口会明确给出无法渲染的状态反馈。由此可见,`Game` 视口本质上是运行时渲染结果在编辑器中的嵌入显示窗口。
`GameViewPanel` 在显示画面的同时,还会把当前帧的键盘、鼠标位置、按键状态和滚轮状态整理为 `GameViewInputFrameEvent` 并发布到事件总线中。随后 `PlaySessionController` 在播放模式下接收该事件,并将其转换为 `InputManager` 可识别的输入数据。因此,`Game` 视口不仅承担画面展示功能,还承担了编辑器到运行时输入桥接的作用。
此处建议插入图 6-2“Scene 视口与 Game 视口对照截图”,用于展示二者在观察目的、交互方式和输出内容上的差异。
### 6.3.4 视口与渲染主链的关系
无论是 `Scene` 视口还是 `Game` 视口,当前项目都没有为其单独实现一套完全不同的渲染器。两类视口都通过 `ViewportHostService` 接入现有的 `SceneRenderer` 和渲染请求生成流程,只是在相机来源、附加渲染通道和输入处理方式上有所区别。这样做的意义在于,编辑器视口所展示的结果与引擎实际渲染能力保持一致,既减少了重复实现,也使视口验证具有更高的可信度。
## 6.4 编辑器交互与调试辅助能力
### 6.4.1 对象选择与场景编辑交互
在场景编辑过程中,对象选择是最基础也是最频繁的交互。当前项目同时提供了层级树选择和视口直接拾取两种方式。前者由 `HierarchyPanel` 完成,用户可以在对象树中展开、选中、重命名对象,并通过拖放改变父子层级关系;后者则由 `Scene` 视口中的对象 ID 拾取流程完成,系统通过离屏对象 ID 纹理读回鼠标位置对应的实体编号,再同步到选择管理器。
对象选中之后,相关状态会立即反馈到其他面板。`InspectorPanel` 会切换到对应对象的组件检查界面,`Scene` 视口会刷新轮廓高亮和 Gizmo层级面板也会保持当前选中状态。这种以统一选择状态为中心的交互方式使用户既可以从结构树编辑场景也可以直接在视口中完成对象定位与操作。
### 6.4.2 变换 Gizmo 与辅助显示
为了提高场景编辑效率,`Scene` 视口实现了较为完整的变换交互辅助能力。当前代码中已经包含平移、旋转、缩放三类 Gizmo以及用于协调三者状态的 `SceneViewportTransformGizmoCoordinator`。用户可在视口中直接拖动控制柄修改对象变换,并在交互过程中结合撤销管理器记录编辑操作。这使编辑器具备了较为明确的几何编辑能力,而不只是参数填写工具。
除变换 Gizmo 外,视口中还实现了场景网格、选中轮廓、方向指示器和 HUD 叠加层等辅助显示内容。网格用于增强空间尺度感选中轮廓用于强化对象定位方向指示器用于辅助相机朝向理解HUD 则用于补充编辑状态显示。这些辅助内容虽然不直接参与运行时渲染结果,但对于编辑器的可用性和调试效率具有重要作用。
此处建议插入图 6-3“Scene 视口交互界面截图”,重点展示对象选中轮廓、场景网格和变换 Gizmo 的叠加效果。
### 6.4.3 导航控制与交互状态管理
`SceneViewPanel` 还围绕编辑视口建立了较完整的导航状态管理机制。当前支持的交互包括观察、平移、环绕、聚焦选中对象以及基于键鼠组合的视角移动。面板内部会根据鼠标按键状态、快捷键状态、工具模式和当前是否存在激活中的 Gizmo 来判断当前交互应解释为视口导航还是对象编辑,并进一步决定是否由 ImGui 捕获鼠标或键盘输入。
这种交互状态管理对于编辑器而言十分关键。如果缺少这一层协调,视口观察、对象拖拽、快捷键切换和界面点击很容易相互冲突。当前项目通过专门的交互解析与导航状态更新流程,把不同输入意图区分开来,使 `Scene` 视口能够在复杂编辑状态下保持稳定响应。
## 6.5 资源与脚本工作流支撑
### 6.5.1 项目资源浏览与导入状态反馈
`ProjectPanel` 是当前编辑器中承担工程资源工作流的主要界面。该面板左侧以树状结构展示项目文件夹,右侧以资源网格方式显示当前目录内容,并提供面包屑导航、搜索、右键上下文菜单、拖放移动、重命名以及新建文件夹和材质资源等功能。对于图像资源,面板还可以直接显示缩略图预览,从而提高资源识别效率。
除了资源浏览本身,`ProjectPanel` 还会显示资源导入状态和场景加载状态。其工具栏可以读取 `ResourceManager::GetProjectAssetImportStatus()` 返回的导入快照,并把当前导入操作、耗时和成功与否展示出来;同时也会读取 `SceneManager` 维护的场景加载进度信息,用于反馈当前场景是否仍有异步资源尚未完成。这使资源管理不再停留在文件浏览层面,而是能够反映资源进入运行时之前的真实处理状态。
### 6.5.2 场景文档与运行模式工作流
编辑器中的场景工作流主要由 `SceneManager``PlaySessionController` 共同完成。`SceneManager` 负责场景创建、对象创建与删除、对象复制与粘贴、层级移动、场景加载与保存,以及场景脏标记维护;同时还支持场景快照捕获与恢复。对于编辑工作而言,这意味着场景既是可视化内容容器,也是可以被保存、恢复和回滚的文档对象。
在运行模式切换方面,`PlaySessionController` 提供了播放、停止、暂停、恢复和单步执行等控制能力,并通过事件总线与顶部运行工具条联动。进入播放模式前,控制器会保存当前编辑场景快照并清空撤销历史,然后启动运行时循环;停止播放时,再恢复编辑态快照并回到普通编辑模式。这一机制把“编辑场景”和“验证运行结果”衔接在一起,是当前编辑器工作流中最能体现工程闭环的一部分。
### 6.5.3 脚本程序集与调试支撑
当前项目已经具备基于 C# 的脚本系统,因此编辑器也必须承担脚本工作流支撑任务。`Application` 在初始化编辑器时会尝试从 `Library/ScriptAssemblies` 目录加载 `XCEngine.ScriptCore.dll``GameScripts.dll` 和相关运行时程序集;如果程序集不存在,编辑器会明确记录状态信息并禁用脚本类发现。与此同时,编辑器还提供了脚本程序集重建与脚本运行时重载能力,使脚本修改后能够重新进入编辑器工作流。
在对象检查层面,`InspectorPanel` 通过 `ComponentEditorRegistry``Transform``Camera``Light``MeshFilter``MeshRenderer``ScriptComponent` 等组件注册了对应的编辑器从而使对象属性面板不仅能显示组件数据还能承担组件参数编辑和脚本组件检查的任务。对于材质资源Inspector 还支持单独的材质资源检查与保存流程,这进一步体现了编辑器对资源系统的深入接入。
在调试支撑方面,`ConsolePanel` 提供了日志级别筛选、折叠显示、搜索、清空、错误暂停、详情查看和源位置打开等功能。控制台不仅能够查看普通日志,还能够在播放模式中配合错误暂停机制辅助脚本调试。这样一来,脚本编译、运行验证和错误定位便能够在同一个编辑器环境中完成。
## 6.6 本章小结
本章围绕当前项目中的编辑器与工作流实现进行了分析。可以看到编辑器是建立在渲染引擎运行时、资源系统、场景系统和脚本系统之上的统一工作界面。在结构上系统通过各类面板完成了编辑器的整体组织在界面上形成了菜单栏、双视口、层级面板、属性面板、项目资源面板和控制台共同构成的工作布局在功能上又通过对象拾取、Gizmo 交互、离屏视口、播放控制、资源导入反馈、脚本重载和日志调试等能力,把编辑、验证与调试串联成完整流程。
对于本课题后续的体积渲染扩展而言,编辑器部分的意义在于提供了稳定的验证和展示平台。无论后续体积渲染模块以何种方式接入现有渲染主链,都可以借助当前编辑器的视口、资源工作流和调试能力完成参数调整、效果观察和结果记录。因此,编辑器与工作流部分不仅体现了当前渲染引擎的工程完整性,也为后续高级渲染模块的并入提供了必要支撑。