Unloading Instanced Levels

I am creating streaming level instances for a semi-procedural dungeon system (using the Get Streaming Level + Create Instance nodes), but I can’t figure out how to unload them once I am done with them.

The Unload Streaming Level node takes a level path input, so I imagine it will unload the source level that the instances are based on, therefore unloading all instances of that level, which is not what I want.

The Create Instance node has return value output, but no way to promote it as a variable, so I can’t refer to it later on once I need to unload that instance.

Does such a feature exist, and if not, what is the ETA or workaround for it?


When you call CreateInstance you provide a unique level name to it. You can use that name later to find created streaming level instance using GetStreamingLevel node. And unload it by setting ShouldBeLoaded to false. It should unload only level instance with that name without affecting other copies. However there is no way now to delete StreamingLevel instance from blueprints, but I think it not really needed.

I’m working on an endless runner type of prototype where the “tiles” are loaded as streaming levels (maps/levels loaded as instances with an offset).

I noticed that after a while (several hundred instances), calls to GetStreamingLevel get very slow and produce huge performance spikes (presumably because the internal reference list gets too large, although I find it somewhat strange that a string based search, which should be easy to sort internally, is such a performance problem with just a couple hundred items - but according to SessionFrontEnd/Profiler GetStreamingLevel is the sole culprit).

I tried to figure out, how to effectively destroy a streaming level instance, without luck, the comment above shattered my hopes.

Is there still no way to do it from blueprint?
Maybe some pointers how to achieve it in C++?

In c++ you can use bIsRequestingUnloadAndRemoval flag in ULevelStreaming. Set it to ‘true’ and engine will remove that level streaming object once sub-level is unloaded.

Ok, thanks, I will have a look at the easiest way to integrate C++.

My first thought was to see if I could make a child class of ULevelStreaming in C++ and expose that property to BP, but that probably wouldn’t be feasible (how would the system know to handle streaming levels as that class?).

I guess, it would suffice to add a function anywhere in code (c++ child class of game mode for instance or any actor for that matter) that would get the streaming level by name and set the flag.

Well, I’ll have to research that (didn’t go further into C++ in UE4 than the “Vehicle Game” project). Thanks for the quick reply about bIsRequestingUnloadAndRemoval.

I was able to expose the property to BP.
In the end it turned out not to be the culprit at all (i.e. GetStreamingLevel is fine even with 1,000 instances), but I learned a lot in the process.

Instead of using create Instance level, use Create Instance. This is an old Kismet function left inside the engine from UDK3.

target is streaming level, give it a unique name ( like appending a random integer to the level name. When you set should be loaded and should be visible to true, it will load on the level, and unload if you set them false.

Important thing is, this node won’t be visible unless you turn of context-sensitive on bp node search.

Also, this note will always give a warning since it is so outdated but it was still working on 4.21 with no problem. Remember that because of that warning bp nativization may or may now work, I never tested it with this node.

To unload a level instance that is loaded in from the node Load Level Instance,
use the node “Set is requesting unload and removal” from the level instance reference and the level will be unloaded.

1 Like