Level Streaming 40+ Levels Performance

I’m currently working on an endless runner game, and I’ve managed to use Level streaming instead of placing actors on the scene.

Let’s assume I have 40+ Sub levels within one Persistent Level, but they are all hidden, and the game loads only two or three of these levels at a time, and as the player overlaps a trigger box, it loads two more, and unloads the previous ones.

The question is: is this okay performance wise? I mean this many sub-levels within one persistent level won’t cause performance issues?

If a level is unloaded, it won’t affect the game’s performance at all right? that means I can have an infinite amount of sublevels within the editor. but managing this high amount of levels won’t cause the engine to crash or generate performance issues at runtime/or in the editor?

Sorry for my bad grammar, and I hope you can understand the question and it makes a little sense to you.

Thanks for the answers in advance!

I’m doing something similar with unloading levels and loading in new ones. Apparently unloading doesn’t actually delete them properly. When I keep loading in levels and unloading other ones, I do see my fps start to drop. I haven’t found a solution to this yet though.

Yes! my FPS drops a bit either when I unload the previous levels. Thanks for your answer anyways! Hope we’ll find a solution to this soon.

I’m doing something similar. Very interested if someone knows something.

I saw an answer to this being the following:

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.

I’m wondering how to access this in c++ or expose it to blueprint somehow.

It is actually interesting. Unfortunately I’m doing my project entirely in Blueprint so yes, exposing it to blueprints could be the only option, if only there is a way for it…

I am currently using 120 sub levels in single level. When I switch between sub levels, It takes less than 2 sec.

But when I start the game it take ridiculous amount of time more than 15 minutes. Any help on this ?

l3D3R do you mind if I ask how big are those sub-levels? I mean how many meshes and actors placed on them approximately?

Is ULevelStreaming a c++ in my projects sln project or something?

I found bIsRequestingUnloadAndRemoval in my levelstreaming.h and put the ‘UPROPERTY’ tag above it. Seems it’s not that simple to get it to show in blueprint.

Here’s a step by step instruction I gave [USER=“1115524”]Jack W Lewis[/USER] in the UE4 Subreddit recently.
Maybe someone here finds it useful, too.

  1. In the Editor go to File->New C++ Class

  2. Select “Blueprint Function Library

  3. Choose a name (leave the directory as is), in this example we’ll keep “MyBlueprintFunctionLibrary”

  4. Unreal will create and compile the new files for you

  5. In your file explorer go to the previously selected folder (default: “<yourproject path>/Source/<ProjectName>”)
    and open the two files with the name you have chosen in step 3, ending with .cpp and .h respectively

5.1. In “<YourNewFile>.h” find:


**#include "<YourFileName>.generated.h"** 

*above *that line add:


**#include "Kismet/GameplayStatics.h"**
**#include "Runtime/Engine/Classes/Engine/LevelStreaming.h"**

5.2. Farther down, find:


**GENERATED_BODY()**

*below *that line add:


**public:
  UFUNCTION(BlueprintCallable, Category = "Some Category")
  static bool DestroyStreamingLevelInstance(FString LevelName, AActor* Sender);**

5.3. In “.cpp” at the end add:


**bool UMyBlueprintFunctionLibrary::DestroyStreamingLevelInstance(FString LevelName, AActor* Sender)
{
    if (Sender) {
        UWorld *WorldReference = Sender->GetWorld();
        if (WorldReference) {
            ULevelStreaming *pStreaming = UGameplayStatics::GetStreamingLevel(WorldReference, FName(*LevelName));
            if (pStreaming)
            {
                pStreaming->bShouldBeLoaded = false;
                pStreaming->bShouldBeVisible = false;
                pStreaming->bIsRequestingUnloadAndRemoval = true;

                return true;
            }
        }
    }
    return false;
}**

  1. Hit the “Compile” button in the Editor’s toolbar

  2. “DestroyStreamingLevelInstance” will now be available as a node you can place in your blueprints.
    Note: Set “Self” (or any valid Actor) as “Sender” and as “LevelName” enter the name of the level instance you want cleared.

This node unloads a streaming level instance but also removes that instance completely.

There is a bit of overhead, but it isn’t significant in most cases where you add sublevels in the editor.
I have answered a similar question recently and posted some test numbers.
Though when you start approaching “an infinite amount of sublevels”, as in the case of an Endless Runner, you risk running into a problem where the size of the internal array that stores all those instances (active and inactive) could cause the performance issue you are experiencing.
The code exposed to BP above would remedy that issue, as the instance will be removed from that array.

How are those levels set up?
Is their Streaming Method set to ***Always ***or Blueprint?
How do you trigger their loading?