Fix PIE deadlock when playing a scene without a primary camera
BuildFrame returned false (skip frame) when the game view had no primary camera, skipping the WaitFence/ResetFence/submit chain - the frame-slot fence never got signaled, so the next WaitFence on that slot blocked forever. Reproduced instantly by playing an empty scene with embedded PIE; latent in manual fullscreen preview too. Game view now falls back to the editor camera instead of skipping the frame, keeping the per-slot fence cadence intact. Viewport warning text updated to mention the editor-view fallback.
This commit is contained in:
@@ -310,8 +310,8 @@ std::optional<entt::entity> ViewportPanel::Draw(const EditorContext &ctx,
|
|||||||
// 占一行布局 → 滚动条出现/消失循环 → avail 抖动 → 渲染分辨率
|
// 占一行布局 → 滚动条出现/消失循环 → avail 抖动 → 渲染分辨率
|
||||||
// 每帧重报(视口疯狂顶动);且默认字体无中文字形(显示 ?)
|
// 每帧重报(视口疯狂顶动);且默认字体无中文字形(显示 ?)
|
||||||
if (playing) {
|
if (playing) {
|
||||||
// 运行态无 primary 相机实体 = 游戏画面黑屏(BuildFrame
|
// 运行态无 primary 相机实体:渲染回退编辑器视角(保持帧
|
||||||
// 跳帧),提示补相机(Hierarchy 右键或 Add Component)
|
// 管线节拍),提示补相机
|
||||||
ECS::TransformComponent *camT = nullptr;
|
ECS::TransformComponent *camT = nullptr;
|
||||||
if (ViewCamera(ctx, camT) == nullptr) {
|
if (ViewCamera(ctx, camT) == nullptr) {
|
||||||
const ImVec2 imgMin = ImGui::GetItemRectMin();
|
const ImVec2 imgMin = ImGui::GetItemRectMin();
|
||||||
@@ -319,8 +319,9 @@ std::optional<entt::entity> ViewportPanel::Draw(const EditorContext &ctx,
|
|||||||
ImVec2(imgMin.x + 8.0f,
|
ImVec2(imgMin.x + 8.0f,
|
||||||
imgMin.y + size.y * 0.5f),
|
imgMin.y + size.y * 0.5f),
|
||||||
IM_COL32(255, 120, 80, 230),
|
IM_COL32(255, 120, 80, 230),
|
||||||
"No primary camera entity - add a Camera "
|
"No primary camera entity - showing editor "
|
||||||
"component and check 'Primary'");
|
"view. Add a Camera component and check "
|
||||||
|
"'Primary'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -278,16 +278,21 @@ namespace Engine
|
|||||||
if (m_DisplayMode == kDisplayViewport && !m_GameView) {
|
if (m_DisplayMode == kDisplayViewport && !m_GameView) {
|
||||||
camTransform = &m_EditorCamera.GetTransform();
|
camTransform = &m_EditorCamera.GetTransform();
|
||||||
camera = &m_EditorCamera.GetController();
|
camera = &m_EditorCamera.GetController();
|
||||||
} else if (auto* cameraComp = scene.GetPrimaryCamera(&camTransform)) {
|
} else {
|
||||||
|
if (auto* cameraComp = scene.GetPrimaryCamera(&camTransform)) {
|
||||||
camera = &cameraComp->camera;
|
camera = &cameraComp->camera;
|
||||||
}
|
}
|
||||||
if (!camera || !camTransform) {
|
if (!camera || !camTransform) {
|
||||||
// 游戏形态无 primary 相机:本帧跳过(安全网)
|
// 游戏形态无 primary 相机:回退编辑器相机渲染(视口有
|
||||||
return false; // 拾取请求未消费,留待下一帧重试
|
// 橙色提示引导补相机)。绝不能跳帧——跳过 submit 会漏
|
||||||
|
// 掉本槽位 fence 的 signal,下一轮该槽位 WaitFence 永
|
||||||
|
// 久阻塞 = 整个渲染死锁(空场景 Play 卡死的根因)
|
||||||
|
camTransform = &m_EditorCamera.GetTransform();
|
||||||
|
camera = &m_EditorCamera.GetController();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 拾取请求落帧(一次性消费:本帧 HitProxy 渲染 + 像素拷贝)。
|
// 拾取请求落帧(一次性消费:本帧 HitProxy 渲染 + 像素拷贝)
|
||||||
// 放在相机校验之后:跳帧时请求保留,不丢点击
|
|
||||||
m_Frame.pickRequest = m_PendingPick;
|
m_Frame.pickRequest = m_PendingPick;
|
||||||
m_PendingPick.active = false;
|
m_PendingPick.active = false;
|
||||||
// 选中实体落帧(持续状态,不做一次性清除)。
|
// 选中实体落帧(持续状态,不做一次性清除)。
|
||||||
|
|||||||
Reference in New Issue
Block a user