Description

Changing bIsSpatiallyLoaded can cause an Actor to be duplicated during Play-In-Editor.
As described in the steps to reproduce, if we keep swapping bIsSpatiallyLoaded state and save a Streaming Level, we eventually end up in a state where the Actor from the Editor World is copied over to PIE, and it is also spawned by the World Partition Manager, duplicating it. By adding a PrintString to the BP_ReproActor BeginPlay printing GetLevel->GetObjectPathString, we see: LogBlueprintUserMessages: [BP_ReproActor_C_UAID_C87F5463DA3888AC02_1894905064] /Game/Maps/UEDPIE_0_ReproMap.ReproMap:PersistentLevel and LogBlueprintUserMessages: [BP_ReproActor_C_UAID_C87F5463DA3888AC02_1894905064] /Memory/UEDPIE_0_ReproMap_7EBELIVHKYDQQSMN1DE5MJVGW.ReproMap:PersistentLevel
Both have the same ID but live in different levels.
I've added a breakpoint in AActor::PostRegisterAllComponents() and was able to see both versions of the BP_ReproActor and their respective callstacks (I'll attach them below).
The situation is not permanent as reopening the level or closing and opening the Editor flush this state and fix the issue.
It looks like an edge case where the Actor is being treated as both being spatially loaded and not - it is copied to the PIE session and also spawned by the Streaming Manager.
I've tested and confirmed this reproduces in 5.6, 5.7, and 5.8 (CL48797988).

Steps to Reproduce

In a blank project, create a Empty Open World level and Save it as ReproMap
Create an actor blueprint (BP_ReproActor) containing a cube component and drag n drop it in the world partition map somewhere close to zero to make sure it is loaded when going in PIE.
Make sure the actor has "Is Spatially Loaded" true.
Save the world.
Go in PIE, at this point, look at the Outliner, you will only have one instance of this actor loaded, which is fine.
Stop PIE.
Select the actor and change its "IsSpatiallyLoaded" flag to false.
Save the world.
Go in PIE again, at this point, everything is still fine and you only have one instance of the actor.
Stop PIE.
Change the "IsSpatiallyLoaded" flag back to "true".
Save the world.
Go in PIE.

Expected result: the actor should, again, show only once in the Outliner.
Actual result: the actor is twice in the Outliner with the same GUID and 2 instances of this actor have been initialized (i.e., "BeginPlay").

Callstack

Call stack for first time PostRegisterAllComponents is called for BP_ReproActor:

> UnrealEditor-Engine.dll!AActor::PostRegisterAllComponents() Line 4090 C++
UnrealEditor-Engine.dll!AActor::IncrementalRegisterComponents(int NumComponentsToRegister, FRegisterComponentContext * Context) Line 6222 C++
UnrealEditor-Engine.dll!ULevel::IncrementalRegisterComponents(FRegisterComponentContext & Context) Line 2001 C++
UnrealEditor-Engine.dll!ULevel::IncrementalUpdateComponents(int NumComponentsToUpdate, bool bRerunConstructionScripts, FRegisterComponentContext * InContext) Line 1865 C++
UnrealEditor-Engine.dll!ULevel::UpdateLevelComponents(bool bRerunConstructionScripts, FRegisterComponentContext * Context) Line 1663 C++
UnrealEditor-Engine.dll!UWorld::UpdateWorldComponents(bool bRerunConstructionScripts, bool bCurrentLevelOnly, FRegisterComponentContext * Context) Line 2804 C++
UnrealEditor-Engine.dll!UWorld::InitializeActorsForPlay(const FURL & InURL, bool bResetTime, FRegisterComponentContext * Context) Line 5734 C++
UnrealEditor-Engine.dll!UGameInstance::StartPlayInEditorGameInstance(ULocalPlayer * LocalPlayer, const FGameInstancePIEParameters & Params) Line 528 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::CreateInnerProcessPIEGameInstance(FRequestPlaySessionParams & InParams, const FGameInstancePIEParameters & InPIEParameters, int InPIEInstanceIndex) Line 3182 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::OnLoginPIEComplete_Deferred(int LocalUserNum, bool bWasSuccessful, FString ErrorString, FPieLoginStruct DataStruct) Line 1627 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::CreateNewPlayInEditorInstance(FRequestPlaySessionParams & InRequestParams, const bool bInDedicatedInstance, const EPlayNetMode InNetMode) Line 1890 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::StartPlayInEditorSession(FRequestPlaySessionParams & InRequestParams) Line 2913 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::StartQueuedPlaySessionRequestImpl() Line 1204 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::StartQueuedPlaySessionRequest() Line 1105 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 2038 C++
UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 533 C++
UnrealEditor-Win64-DebugGame.exe!FEngineLoop::Tick() Line 5625 C++
[Inline Frame] UnrealEditor-Win64-DebugGame.exe!EngineTick() Line 60 C++
UnrealEditor-Win64-DebugGame.exe!GuardedMain(const wchar_t * CmdLine) Line 187 C++
UnrealEditor-Win64-DebugGame.exe!LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 271 C++
UnrealEditor-Win64-DebugGame.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 339 C++
[External Code]

Call stack for the second time PostRegisterAllComponents is called for BP_ReproActor:

> UnrealEditor-Engine.dll!AActor::PostRegisterAllComponents() Line 4090 C++
UnrealEditor-Engine.dll!AActor::IncrementalRegisterComponents(int NumComponentsToRegister, FRegisterComponentContext * Context) Line 6222 C++
UnrealEditor-Engine.dll!ULevel::IncrementalRegisterComponents(FRegisterComponentContext & Context) Line 2001 C++
UnrealEditor-Engine.dll!ULevel::IncrementalUpdateComponents(int NumComponentsToUpdate, bool bRerunConstructionScripts, FRegisterComponentContext * InContext) Line 1865 C++
UnrealEditor-Engine.dll!UWorld::AddToWorld(ULevel * Level, const UE::Math::TTransform<double> & LevelTransform, bool bConsiderTimeLimit, const TOptional<UE::FTimeout const> & ExternalTimeout, FNetLevelVisibilityTransactionId TransactionId, ULevelStreaming * InOwningLevelStreaming) Line 3688 C++
UnrealEditor-Engine.dll!ULevelStreaming::UpdateStreamingState(bool & bOutUpdateAgain, bool & bOutRedetermineTarget, const TOptional<UE::FTimeout const> & InExternalTimeout) Line 1056 C++
[Inline Frame] UnrealEditor-Engine.dll!FStreamingLevelPrivateAccessor::UpdateStreamingState(ULevelStreaming *) Line 804 C++
UnrealEditor-Engine.dll!UWorld::UpdateLevelStreaming(const TOptional<UE::FTimeout const> & ExternalTimeout) Line 4903 C++
[Inline Frame] UnrealEditor-Engine.dll!UWorld::FlushLevelStreaming::__l2::<lambda_1>::operator()() Line 5165 C++
UnrealEditor-Engine.dll!UWorld::FlushLevelStreaming(EFlushLevelStreamingType FlushType) Line 5168 C++
UnrealEditor-Engine.dll!UWorld::BlockTillLevelStreamingCompleted() Line 4650 C++
UnrealEditor-Engine.dll!UEngine::BlockTillLevelStreamingCompleted(UWorld * InWorld) Line 16267 C++
UnrealEditor-Engine.dll!UGameInstance::StartPlayInEditorGameInstance(ULocalPlayer * LocalPlayer, const FGameInstancePIEParameters & Params) Line 546 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::CreateInnerProcessPIEGameInstance(FRequestPlaySessionParams & InParams, const FGameInstancePIEParameters & InPIEParameters, int InPIEInstanceIndex) Line 3182 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::OnLoginPIEComplete_Deferred(int LocalUserNum, bool bWasSuccessful, FString ErrorString, FPieLoginStruct DataStruct) Line 1627 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::CreateNewPlayInEditorInstance(FRequestPlaySessionParams & InRequestParams, const bool bInDedicatedInstance, const EPlayNetMode InNetMode) Line 1890 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::StartPlayInEditorSession(FRequestPlaySessionParams & InRequestParams) Line 2913 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::StartQueuedPlaySessionRequestImpl() Line 1204 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::StartQueuedPlaySessionRequest() Line 1105 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 2038 C++
UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 533 C++
UnrealEditor-Win64-DebugGame.exe!FEngineLoop::Tick() Line 5625 C++
[Inline Frame] UnrealEditor-Win64-DebugGame.exe!EngineTick() Line 60 C++
UnrealEditor-Win64-DebugGame.exe!GuardedMain(const wchar_t * CmdLine) Line 187 C++
UnrealEditor-Win64-DebugGame.exe!LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 271 C++
UnrealEditor-Win64-DebugGame.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 339 C++
[External Code]

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-358608 in the post.

0
Login to Vote

Unresolved
CreatedDec 18, 2025
UpdatedFeb 26, 2026
View Jira Issue