Possible streaming level bug?


I am working on a game that uses world composition.
I got a main level (Persistent level) that contains pretty much just the skydome.
I have also got a menu screen where when I hit “play” I am calling down to my code to create the player character,
associate a controller and make it generally spawn in a certain position of my world (i.e. 0,0,0).

Before doing that I call this helper function to open my game world level
UGameplayStatics::OpenLevel(GetWorld(), *MapName);

with “MapName” being the name of my persistent level and GetWorld() being the current “main menu world”.
It all spawns in and works as it should EXCEPT
when I move too far away from 0,0,0 the streaming kicks in via

void UWorld::UpdateLevelStreamingInner( UWorld* PersistentWorld, FSceneViewFamily* ViewFamily )

and that is where things start going wrong.
the streaminglevels first entry is the “persistentlevel” and it gets removed from the world.
Note the world has the PersistentLevel variable set to the correct “persistenlevel” that i requested to be loaded.
But that level doesnt have any bounds (the sub levels have) and thus fails this check

bShouldBeLoaded	= bShouldBeLoaded  || !IsGameWorld() || StreamingLevel->ShouldBeLoaded(ViewLocation);

but in my opinion it shouldnt even get to that point. bShouldBeLoaded should already be set to true if the StreamingLevel (or level[0]) is the persistent level. It should never remove that level.

Unless I am missing something when I load my persistent world this looks like a simple fix of

bShouldBeLoaded = bShouldBeLoaded	 || StreamingLevel->GetLoadedLevel()->IsPersistentLevel();

any ideas / suggestions ?


okay so I tried modifying the engine code , and it works. No more crash because the persistent level unloaded.

here is the code I added in the above mentioned method of UWorld

        bool bIsPersistentLevel = StreamingLevel->GetLoadedLevel() && StreamingLevel->GetLoadedLevel()->IsPersistentLevel();

		// Figure out whether level should be loaded, visible and block on load if it should be loaded but currently isn't.
		bool bShouldBeLoaded				= bHasVisibilityRequestPending || (!GEngine->bUseBackgroundLevelStreaming && !PersistentWorld->bShouldForceUnloadStreamingLevels && !StreamingLevel->bIsRequestingUnloadAndRemoval);
             bShouldBeLoaded                = bShouldBeLoaded || bIsPersistentLevel;
		bool bShouldBeVisible				= bHasVisibilityRequestPending || PersistentWorld->bShouldForceVisibleStreamingLevels;
             bShouldBeVisible               = bShouldBeVisible || bIsPersistentLevel;
		bool bShouldBlockOnLoad				= StreamingLevel->bShouldBlockOnLoad;

as you can see basically i consider PersistentLevels to be always loaded and visible .that stops them from being removed by the streaming system.

I should have added I am on 4.6.0 and running PIE.


Persistent level should not be among streaming levels, this is a bug and fixed here:

Fix will be a part of 4.7 version.