diff --git a/engine/src/Scripting/Mono/MonoScriptRuntime.cpp b/engine/src/Scripting/Mono/MonoScriptRuntime.cpp index c6566368..c57a1b8f 100644 --- a/engine/src/Scripting/Mono/MonoScriptRuntime.cpp +++ b/engine/src/Scripting/Mono/MonoScriptRuntime.cpp @@ -3389,8 +3389,9 @@ void MonoScriptRuntime::OnRuntimeStart(Components::Scene* scene) { } void MonoScriptRuntime::OnRuntimeStop(Components::Scene* scene) { - (void)scene; - ClearManagedRenderPipelineSelection(this); + if (scene != nullptr) { + ClearManagedRenderPipelineSelection(this); + } ClearManagedInstances(); m_activeScene = nullptr; GetInternalCallScene() = nullptr; diff --git a/engine/src/Scripting/ScriptEngine.cpp b/engine/src/Scripting/ScriptEngine.cpp index 4de21870..4d38745d 100644 --- a/engine/src/Scripting/ScriptEngine.cpp +++ b/engine/src/Scripting/ScriptEngine.cpp @@ -155,12 +155,17 @@ void ScriptEngine::OnRuntimeSceneReplaced(Components::Scene* scene) { return; } + if (m_runtimeScene && m_runtimeSceneCreatedSubscription != 0) { + m_runtimeScene->OnGameObjectCreated().Unsubscribe(m_runtimeSceneCreatedSubscription); + m_runtimeScene->OnGameObjectCreated().ProcessUnsubscribes(); + m_runtimeSceneCreatedSubscription = 0; + } + const float configuredFixedDeltaTime = m_runtimeFixedDeltaTime; m_runtime->OnRuntimeStop(nullptr); m_runtimeFixedDeltaTime = configuredFixedDeltaTime; m_runtimeScene = scene; - m_runtimeSceneCreatedSubscription = 0; m_scriptStates.clear(); m_scriptOrder.clear(); diff --git a/tests/scripting/test_mono_script_runtime.cpp b/tests/scripting/test_mono_script_runtime.cpp index cfb08423..c9234de0 100644 --- a/tests/scripting/test_mono_script_runtime.cpp +++ b/tests/scripting/test_mono_script_runtime.cpp @@ -414,6 +414,61 @@ TEST_F( EXPECT_EQ(host->GetStageRecorder(), nullptr); } +TEST_F( + MonoScriptRuntimeTest, + RuntimeSceneReplacePreservesManagedGraphicsSettingsSelection) { + Scene* firstScene = CreateScene("ManagedRenderPipelineFirstScene"); + GameObject* selectionObject = + firstScene->CreateGameObject("ManagedRenderPipelineSelection"); + ScriptComponent* selectionScript = + AddScript( + selectionObject, + "Gameplay", + "ManagedRenderPipelineRuntimeSelectionProbe"); + ASSERT_NE(selectionScript, nullptr); + + engine->OnRuntimeStart(firstScene); + engine->OnUpdate(0.016f); + + const XCEngine::Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptorBeforeReplace = + XCEngine::Rendering::Pipelines::GetManagedRenderPipelineAssetDescriptor(); + ASSERT_TRUE(descriptorBeforeReplace.IsValid()); + ASSERT_NE(descriptorBeforeReplace.managedAssetHandle, 0u); + MonoObject* const managedAssetBeforeReplace = + runtime->GetExternalManagedObject( + descriptorBeforeReplace.managedAssetHandle); + ASSERT_NE(managedAssetBeforeReplace, nullptr); + + auto secondScene = std::make_unique("ManagedRenderPipelineSecondScene"); + engine->OnRuntimeSceneReplaced(secondScene.get()); + scene = std::move(secondScene); + + const XCEngine::Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptorAfterReplace = + XCEngine::Rendering::Pipelines::GetManagedRenderPipelineAssetDescriptor(); + EXPECT_EQ(descriptorAfterReplace.assemblyName, descriptorBeforeReplace.assemblyName); + EXPECT_EQ(descriptorAfterReplace.namespaceName, descriptorBeforeReplace.namespaceName); + EXPECT_EQ(descriptorAfterReplace.className, descriptorBeforeReplace.className); + EXPECT_EQ( + descriptorAfterReplace.managedAssetHandle, + descriptorBeforeReplace.managedAssetHandle); + EXPECT_EQ( + runtime->GetExternalManagedObject( + descriptorAfterReplace.managedAssetHandle), + managedAssetBeforeReplace); + + XCEngine::Rendering::CameraRenderer renderer; + const auto* pipelineAsset = + dynamic_cast< + const XCEngine::Rendering::Pipelines::ManagedScriptableRenderPipelineAsset*>( + renderer.GetPipelineAsset()); + ASSERT_NE(pipelineAsset, nullptr); + EXPECT_EQ( + pipelineAsset->GetDescriptor().className, + descriptorBeforeReplace.className); + + engine->OnRuntimeStop(); +} + TEST_F( MonoScriptRuntimeTest, DefaultCameraRendererUsesManagedGraphicsSelectionToRecordMainSceneGraph) {