Efficient editor workflow for seamless level streaming in UE5? Issue with hidden sub-levels all being loaded into memory when the Persistent Level is loaded in the editor

Hi all, I’m working on an indie project in UE5, and hoping some more experienced devs could chip in regarding workflow for level-streaming and how it should be structured in my project.

Basically, I’m working on a level-based game (not an “open-world”), where I want level transitions to occur seamlessly without loading screens. Also, I want to keep things structured as simply and efficiently as possible.
For this project, you can imagine the player character flying into a warp gate, the previous level unloading during the warp gate animation, and the warp tunnel opening up into the next level after it has been loaded in.

Logically, the current system I’m using seems to make sense. I’m using a single Persistent Level which only contains a post-process volume in order to ensure consistent bloom, exposure, and other graphics settings across the game. Each individual level is placed in this Persistent Level, and loading/unloading is handled from C++ according to the game state. When editing level environments from the editor, in the Levels window I would hide all the levels except for the individual level I am working on. This is a fairly convenient way to switch between levels for editing and previewing purposes.

However, there is one major problem with this approach. When opening the editor with the single Persistent Level as the default map, all the data from all the sub-levels is automatically loaded into memory, even if they are all hidden in the Levels window. This greatly increases editor load time and memory usage, to an extent where I think I need to find a workaround or give up on this approach.

Here are the other posts I found about this same issue, neither of which has been resolved:

This post mentions that enabling the “Use Background Level Streaming” Project Setting would prevent invisible levels from getting automatically loaded into memory in the editor. However, I tested both enabled and disabled, and there wasn’t any difference (all data is loaded into memory regardless):

So I was wondering if anyone happens to know a solution to this problem, or perhaps a better workflow or way to structure level data?

The only alternative I’ve thought of so far is to create an additional Persistent Level for every level in the game (contents: 1. a “common data” level containing the post-process volume + 2. the individual level data). These Persistent Levels would only be for the purpose of previewing/editing levels in the editor, and wouldn’t be used in the final game. Since each of these would only contain the data for a single level, the above memory issue would be avoided. This seems like it would work, but not necessarily be as convenient/simple as my original approach.

Any progress on this front?

Yeah. Just have one empty persistent level with no sub-levels, and make a system to stream in and out levels dynamically as appropriate for your game. Create a clean system for this and you will be able to transition between levels seamlessly without the need for loading screens, except in some situations, such as when returning to the title screen.

Refer to UGameplayStatics::LoadStreamLevel and UGameplayStatics::UnloadStreamLevel (etc).

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.