PIE: viewport-embedded playback with UE-style main toolbar

Play no longer switches to fullscreen direct rendering: PIE now keeps
the editor UI alive and renders the primary camera into the Viewport
panel (new SceneRenderer::SetGameView flag; kDisplayDirect stays a
manual fullscreen preview for later release form). Editor camera stops
being driven during PIE, and viewport click-pick is gated off while
playing (clicks are game input now).

The Play/Stop buttons move out of the menu bar into a dedicated main
toolbar row below it (centered, UE Main Toolbar semantics): green Play
when idle; Pause (yellow, highlighted while paused) + Stop (orange)
while playing. Ctrl+P hotkey kept. Stats "Pause Simulation" merged
into the toolbar Pause; viewport overlay shows PAUSED accordingly.
This commit is contained in:
2026-10-05 11:14:24 +08:00
parent 5ca5ac2a1e
commit 1a278d5945
10 changed files with 167 additions and 67 deletions
@@ -142,6 +142,7 @@ namespace Engine {
// ---- 显示模式(Editor 视口 ↔ 全屏直出;帧首同步生效)----
int GetDisplayMode() const { return m_DesiredDisplayMode; }
void SetDisplayMode(int mode); // cpp 内定义(SceneRenderer 前置声明)
void SetGameView(bool gameView); // PIE 内嵌播放(cpp 转发 SceneRenderer)
// 编辑器相机(Scene view 恒用,与场景相机实体无关)。转发
// SceneRenderer 持有的实例:Application 驱动 Update,面板读写位姿
EditorCamera& GetEditorCamera(); // cpp 内定义(SceneRenderer 完整类型)
@@ -66,6 +66,10 @@ namespace Engine {
void SetLodEnabled(bool b) { m_LodEnabled = b; }
void SetDebugView(int v) { m_DebugView = v; }
void SetDisplayMode(int m) { m_DisplayMode = m; } // kDisplayDirect / kDisplayViewport
// PIE 内嵌播放(UE Play-In-Editor 语义):viewport 模式下也用
// primary 相机渲染进 sceneTex(Play 后 Scene view 显示游戏画面,
// 编辑器 UI 保持可用)。kDisplayDirect 恒为游戏形态不受此影响
void SetGameView(bool g) { m_GameView = g; }
// 编辑器相机(视口 UI 状态,SceneRenderer 持有 = 渲染源在此分派);
// Application 驱动 Update,ViewportPanel/Inspector 经 Renderer 门面访问
EditorCamera& GetEditorCamera() { return m_EditorCamera; }
@@ -171,6 +175,7 @@ namespace Engine {
bool m_LodEnabled = true; // 关 = 全部强制 LOD0(选级跳过)
int m_DebugView = 0;
int m_DisplayMode = kDisplayViewport; // Editor 视口为默认形态
bool m_GameView = false; // PIE 内嵌播放(Editor Play/Stop 驱动)
};
} // namespace Engine
+5
View File
@@ -234,6 +234,11 @@ namespace Engine
m_SceneRenderer->SetDisplayMode(mode);
}
void Renderer::SetGameView(bool gameView)
{
m_SceneRenderer->SetGameView(gameView);
}
EditorCamera& Renderer::GetEditorCamera()
{
return m_SceneRenderer->GetEditorCamera();
+4 -3
View File
@@ -269,12 +269,13 @@ namespace Engine
ubo.prevView = m_LastView;
ubo.prevProj = m_LastProjNoJitter;
// ---- 1. 相机:渲染源按显示模式分派(UE 语义)。编辑器形态
// ---- 1. 相机:渲染源按形态分派(UE 语义)。编辑器形态
// Scene view 恒用编辑器相机(视口 UI 状态,空场景可用);
// 游戏形态用场景 primary 相机实体(游戏逻辑所有)----
// 游戏形态(kDisplayDirect 全屏预览或 PIE 内嵌播放)用
// 场景 primary 相机实体(游戏逻辑所有)----
ECS::TransformComponent* camTransform = nullptr;
const Camera* camera = nullptr;
if (m_DisplayMode == kDisplayViewport) {
if (m_DisplayMode == kDisplayViewport && !m_GameView) {
camTransform = &m_EditorCamera.GetTransform();
camera = &m_EditorCamera.GetController();
} else if (auto* cameraComp = scene.GetPrimaryCamera(&camTransform)) {