From 5affbc7d0de4d8131e3f3dea779d0970133743de Mon Sep 17 00:00:00 2001 From: "j.foucher" Date: Tue, 14 Apr 2026 13:36:12 +0200 Subject: [PATCH] IsLoadingFromScene via static flag, revert network replication on SpawnableComponent - IsLoadingFromScene uses a simple static bool flag active during spawn loop - Works server-side only (client relies on its own property replication) - Removed replicated bLoadedFromScene/bPropertiesReady from SpawnableComponent - Removed Multicast RPC and SetIsReplicatedByDefault (unnecessary complexity) - SceneSerializer sets bIsCurrentlyLoading during load for consistent behavior Co-Authored-By: Claude Opus 4.6 (1M context) --- .../Serialization/PS_Editor_SceneLoader.cpp | 14 +++++--------- .../Serialization/PS_Editor_SceneLoader.h | 5 ++++- .../Serialization/PS_Editor_SceneSerializer.cpp | 4 ++++ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneLoader.cpp b/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneLoader.cpp index 52505ac..69908d9 100644 --- a/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneLoader.cpp +++ b/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneLoader.cpp @@ -89,6 +89,7 @@ bool UPS_Editor_SceneLoader::LoadSceneFromData(UWorld* World, const FPS_Editor_S int32 SpawnedCount = 0; + bIsCurrentlyLoading = true; for (const FPS_Editor_ActorData& ActorData : SceneData.Actors) { AActor* SpawnedActor = SpawnActorFromData(World, ActorData); @@ -98,6 +99,7 @@ bool UPS_Editor_SceneLoader::LoadSceneFromData(UWorld* World, const FPS_Editor_S SpawnedCount++; } } + bIsCurrentlyLoading = false; UE_LOG(LogTemp, Log, TEXT("PS_Editor SceneLoader: Loaded %d actors from scene '%s'"), SpawnedCount, *SceneData.SceneName); @@ -118,13 +120,8 @@ AActor* UPS_Editor_SceneLoader::SpawnActorFromData(UWorld* World, const FPS_Edit return nullptr; } - // Spawn with tag set BEFORE BeginPlay so the BP can skip its default init FActorSpawnParameters SpawnParams; SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn; - SpawnParams.CustomPreSpawnInitalization = [](AActor* Actor) - { - Actor->Tags.Add(FName("PS_Editor_Loading")); - }; AActor* SpawnedActor = World->SpawnActor(LoadedClass, ActorData.Location, ActorData.Rotation, SpawnParams); if (!SpawnedActor) @@ -152,9 +149,6 @@ AActor* UPS_Editor_SceneLoader::SpawnActorFromData(UWorld* World, const FPS_Edit Spline->ImportFromCustomProperties(ActorData.CustomProperties); } - // Remove loading tag now that properties are applied - SpawnedActor->Tags.Remove(FName("PS_Editor_Loading")); - // Notify the actor that all properties are ready if (SpawnedActor->GetClass()->ImplementsInterface(UPS_Editor_EditableInterface::StaticClass())) { @@ -209,9 +203,11 @@ void UPS_Editor_SceneLoader::ApplyCustomProperties(AActor* Actor, const TMapActorHasTag(FName("PS_Editor_Loading")); + return bIsCurrentlyLoading; } FString UPS_Editor_SceneLoader::GetScenesDirectory() diff --git a/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneLoader.h b/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneLoader.h index a8d36e4..3facb6b 100644 --- a/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneLoader.h +++ b/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneLoader.h @@ -71,12 +71,15 @@ public: static FString GetSceneLevelName(const FString& SceneName); /** - * Returns true if this actor is currently being spawned from a scene load. + * Returns true while a scene is being loaded (actors are being spawned from JSON). * Use in BeginPlay to skip default initialization — wait for OnPropertiesLoaded instead. */ UFUNCTION(BlueprintCallable, BlueprintPure, Category = "PS Editor") static bool IsLoadingFromScene(const AActor* Actor); + /** Static flag: true while SceneLoader or SceneSerializer is spawning actors. */ + static bool bIsCurrentlyLoading; + /** * Get all saved scenes for the current level. */ diff --git a/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneSerializer.cpp b/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneSerializer.cpp index cbd6c4b..489c5bf 100644 --- a/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneSerializer.cpp +++ b/Unreal/Plugins/PS_Editor/Source/PS_Editor/Serialization/PS_Editor_SceneSerializer.cpp @@ -4,6 +4,7 @@ #include "PS_Editor_EditableComponent.h" #include "PS_Editor_EditableInterface.h" #include "PS_Editor_PlayerController.h" +#include "PS_Editor_SceneLoader.h" #include "PS_Editor_SplineActor.h" #include "JsonObjectConverter.h" #include "Misc/FileHelper.h" @@ -150,6 +151,7 @@ bool UPS_Editor_SceneSerializer::LoadScene(const FString& SceneName, UPS_Editor_ // Re-spawn actors from saved data int32 SpawnedCount = 0; + UPS_Editor_SceneLoader::bIsCurrentlyLoading = true; for (const FPS_Editor_ActorData& ActorData : SceneData.Actors) { UClass* LoadedClass = LoadObject(nullptr, *ActorData.ClassPath); @@ -228,6 +230,8 @@ bool UPS_Editor_SceneSerializer::LoadScene(const FString& SceneName, UPS_Editor_ } } + UPS_Editor_SceneLoader::bIsCurrentlyLoading = false; + UE_LOG(LogTemp, Log, TEXT("PS_Editor: Scene loaded: %s (%d actors)"), *SceneName, SpawnedCount); return true; }