Download

Resolving the streaming level mess

Hi community
i have this dilemma.I am making a platform puzzle game and I have my maps structured in this way:

-Overworld map ->the level select map

Epic recommend to setup sublevels when working with a team so we are using this setup

-World_01_01_P /persistent container
->World_01_01_Blueprints->Sublevel with logic and bp
->World_01_02_StaticMesh->Sublevel with logic and bp

-World_01_02_P /persistent container
->World_01_02_Blueprints->Sublevel with logic and bp
->World_01_02_StaticMesh->Sublevel with logic and bp

and so, with 5 world, 6 levels each. Every sublevel has Always Loaded.
Overworld opens via OpenLevel method,

so the biggest problem is this:

when you complete the level you load the next level immediate, no need to go back to overworld uniti you finish the last level (or using the main menu)
however using Openlevel freeze the game because loading, and the music is reset.
If you try to restart you must use OpenLevel again with the same effects.

I tried using
UGameplayStatics::LoadStreamLevel but how my levels are composit, it opens the persistent container not the sublevels. i tried to create a World container and put every sublevel on it but it quickly became a mess. then i tried using a world container and load a sublevel using ULevelStreamingKismet but this causes the player to fall down or the gamemode fails to load the playerstart. i i believe i am doing something wrong or my workflow is wrong. how do you guys do it?

btw the code i am using to load levels is this



void AToadProyectGameModeBase::LoadLevelManager(FWorldLevel _worldLevel)
{



    int32 nWorld = _worldLevel.world + 1;
    int32 nLevel = _worldLevel.Level + 1;
    loadingWorldLevel = _worldLevel;

    FString sMapName = FString::Printf(TEXT("Level_0%d_0%d_StaticMeshes"), nWorld, nLevel);
    FString sPackageName = FString::Printf(TEXT("/Game/Maps/World_0%d/Level_0%d/Level_0%d_0%d_StaticMeshes.Level_0%d_0%d_StaticMeshes"), nWorld, nLevel, nWorld, nLevel);

    FName packageNameMesh = FName(*sPackageName);

    staticmeshSublevel = LoadStreamingLevelAsync(packageNameMesh, sMapName);
    staticmeshSublevel->OnLevelLoaded.AddDynamic(this, &AToadProyectGameModeBase::OnLevelsLoadComplete);

    //////////////////////////////////////////////////////////////////////////
    //get blueprint sublevel

    sMapName = FString::Printf(TEXT("Level_0%d_0%d_Starts"), nWorld, nLevel);
    sPackageName = FString::Printf(TEXT("/Game/Maps/World_0%d/Level_0%d/Level_0%d_0%d_Starts.Level_0%d_0%d_Starts"), nWorld, nLevel, nWorld, nLevel);

    packageNameMesh = FName(*sPackageName);
    blueprintSublevel = LoadStreamingLevelAsync(packageNameMesh, sMapName);

    blueprintSublevel->OnLevelLoaded.AddDynamic(this, &AToadProyectGameModeBase::OnLevelsLoadComplete);


}


​​​​​​​


ULevelStreamingKismet* AToadProyectGameModeBase::LoadStreamingLevelAsync(FName packageName, FString mapName)
{
    ULevelStreamingKismet* StreamingLevel = static_cast<ULevelStreamingKismet*>(NewObject<ULevelStreamingKismet>(GetWorld(), NAME_None, RF_NoFlags, NULL));
    // Associate a package name.



    FName PackageNameToLoad = packageName;



    // Associate a package name.
    StreamingLevel->SetWorldAssetByPackageName(PackageNameToLoad);
    if (GetWorld()->IsPlayInEditor())
    {
        FWorldContext WorldContext = GEngine->GetWorldContextFromWorldChecked(GetWorld());
        StreamingLevel->RenameForPIE(WorldContext.PIEInstance);
    }

    StreamingLevel->LevelColor = FColor::MakeRandomColor();
    StreamingLevel->bShouldBeLoaded = true;
    StreamingLevel->bShouldBeVisible = true;
    StreamingLevel->bShouldBlockOnLoad = false;
    StreamingLevel->bInitiallyLoaded = true;
    StreamingLevel->bInitiallyVisible = true;

    StreamingLevel->LevelTransform = FTransform();

    StreamingLevel->PackageNameToLoad = PackageNameToLoad;

    FString PackageFileName;
    if (!FPackageName::DoesPackageExist(StreamingLevel->PackageNameToLoad.ToString(), NULL, &PackageFileName))
    {
        UE_LOG(LogTemp, Error, TEXT("trying to load invalid level %s"), *StreamingLevel->PackageNameToLoad.ToString());

    }

    StreamingLevel->PackageNameToLoad = FName(*FPackageName::FilenameToLongPackageName(PackageFileName));

    // Add the new level to world.
    GetWorld()->StreamingLevels.Add(StreamingLevel);


    return StreamingLevel;




}