Fix play mode runtime scene replacement

This commit is contained in:
2026-04-08 00:33:50 +08:00
parent 69cb80ccd4
commit 23ff4004f4
9 changed files with 149 additions and 0 deletions

View File

@@ -22,6 +22,7 @@ public:
void Start(Scene* scene);
void Stop();
void ReplaceScene(Scene* scene);
void Tick(float deltaTime);
void Pause();

View File

@@ -34,6 +34,7 @@ public:
void Start(Scene* scene);
void Stop();
void ReplaceScene(Scene* scene);
void FixedUpdate(float fixedDeltaTime);
void Update(float deltaTime);

View File

@@ -28,6 +28,7 @@ public:
void OnRuntimeStart(Components::Scene* scene);
void OnRuntimeStop();
void OnRuntimeSceneReplaced(Components::Scene* scene);
void OnFixedUpdate(float fixedDeltaTime);
void OnUpdate(float deltaTime);

View File

@@ -44,6 +44,12 @@ void RuntimeLoop::Stop() {
m_stepRequested = false;
}
void RuntimeLoop::ReplaceScene(Scene* scene) {
m_sceneRuntime.ReplaceScene(scene);
m_fixedAccumulator = 0.0f;
m_stepRequested = false;
}
void RuntimeLoop::Tick(float deltaTime) {
if (!IsRunning()) {
return;

View File

@@ -46,6 +46,18 @@ void SceneRuntime::Stop() {
m_scene = nullptr;
}
void SceneRuntime::ReplaceScene(Scene* scene) {
if (!m_running) {
m_scene = scene;
m_uiRuntime->Reset();
return;
}
m_scene = scene;
m_uiRuntime->Reset();
Scripting::ScriptEngine::Get().OnRuntimeSceneReplaced(scene);
}
void SceneRuntime::FixedUpdate(float fixedDeltaTime) {
if (!m_running || !m_scene || !m_scene->IsActive()) {
return;

View File

@@ -141,6 +141,54 @@ void ScriptEngine::OnRuntimeStop() {
m_runtime->OnRuntimeStop(stoppedScene);
}
void ScriptEngine::OnRuntimeSceneReplaced(Components::Scene* scene) {
if (!m_runtimeRunning) {
m_runtimeScene = nullptr;
m_runtimeSceneCreatedSubscription = 0;
m_scriptStates.clear();
m_scriptOrder.clear();
return;
}
const float configuredFixedDeltaTime = m_runtimeFixedDeltaTime;
m_runtime->OnRuntimeStop(nullptr);
m_runtimeFixedDeltaTime = configuredFixedDeltaTime;
m_runtimeScene = scene;
m_runtimeSceneCreatedSubscription = 0;
m_scriptStates.clear();
m_scriptOrder.clear();
if (!m_runtimeScene) {
return;
}
m_runtime->OnRuntimeStart(m_runtimeScene);
m_runtimeSceneCreatedSubscription = m_runtimeScene->OnGameObjectCreated().Subscribe(
[this](Components::GameObject* gameObject) {
HandleGameObjectCreated(gameObject);
});
for (Components::GameObject* root : m_runtimeScene->GetRootGameObjects()) {
CollectScriptComponents(root);
}
const std::vector<ScriptInstanceKey> startupKeys = m_scriptOrder;
for (const ScriptInstanceKey& key : startupKeys) {
auto it = m_scriptStates.find(key);
if (it == m_scriptStates.end()) {
continue;
}
ScriptInstanceState& state = it->second;
if (!ShouldScriptRun(state)) {
continue;
}
EnsureScriptReady(state, true);
}
}
void ScriptEngine::OnFixedUpdate(float fixedDeltaTime) {
if (!m_runtimeRunning) {
return;