Download

Asynchronous Level Loading with World Composition

Hi.

I am trying to load a level without blocking the entire scene. I am using the functionality highlighted in this post : Package Async Load VS OpenLevel VS Travel - UE4 AnswerHub .

So I first cache the level with LoadPackageAsync(), store the package and world as UProperties, then call UGameplayStatics::OpenLevel. Which seems to be working, except none of the sublevels (using world composition) are being loaded.
For debugging purposes I am printing out all streaming levels in the BeginPlay() of my game mode with GetWorld()->StreamingLevels. When starting the level in PIE all the levels are there, when loading asynchronously the list is empty.

Any idea what I might be missing? Maybe a dev?

I have found the function UWorld::RefreshStreamingLevels(), but that seems to be a synchronized action. Am I on the right track?

I have encountered a new problem: UWorld::RefreshStreamingLevels() seems to only work in PIE, which is weird, so I tried calling the FlushLevelStreaming() function directly. But this one also seems to load the streamed levels in PIE, not in standalone. Is this expected behaviour? Is there any way of making it work outside of PIE?

Edit:
The UWorld::StreamingLevels array is empty in standalone, need to figure out why

I found out that the UWorld::StreaminLevels are emptied somewhere. To circumvent that I refresh it after the map has been initialized with:


const TArray<ULevelStreaming*> TilesStreaming = World->WorldComposition->TilesStreaming;
World->StreamingLevels.Empty();
World->StreamingLevels.Append(TilesStreaming);

It’s working now, but I’d rather have the array not emptied in the first place, so I am going to research that.

For future reference: After level loading, if you want to make sure all of your streaming levels (or your world composition) are fully loaded, you can check like this:


for (ULevelStreaming* StreamingLevel : World->StreamingLevels)
{
    if (StreamingLevel->IsStreamingStatePending())
    {
        return false; // This means not fully loaded. You can build a loop with a delay in your BP for consecutive checks
    }
}

Async loading is working only when game is cooked and proper setting is enabled in project settings, see FAsyncLoadingThread::ShouldBeMultithreaded().
I have asked UE devs to please address this as this is very annoying not to have async behavior during development.

Hi, Is this possible in blueprint?

Thank you for the solution, there is no chance I could find it myself. In my case World Composition worked well in PIE (except the loading delay) but not in Standalone game, it just didn’t try to load anything.
By the way, did you find a root cause?