Skip to content

Instantly share code, notes, and snippets.

@MauritsDijkman
Created January 27, 2024 11:25
Show Gist options
  • Save MauritsDijkman/71b858838251f6073a395824d0adf072 to your computer and use it in GitHub Desktop.
Save MauritsDijkman/71b858838251f6073a395824d0adf072 to your computer and use it in GitHub Desktop.
// Fill out your copyright notice in the Description page of Project Settings.
#include "AsyncLevelLoadSceneComponent.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/PlayerController.h"
UAsyncLevelLoadSceneComponent::UAsyncLevelLoadSceneComponent()
{
PrimaryComponentTick.bCanEverTick = true;
bIsLoading = false;
}
void UAsyncLevelLoadSceneComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (bIsLoading)
{
float localLoadingPercentage = GetAsyncLoadPercentage(FName(*(pLevelDir + pLevelName)));
if (localLoadingPercentage >= 0)
{
loadingPercentage = localLoadingPercentage;
UE_LOG(LogTemp, Log, TEXT("Loading progress: %f%%"), loadingPercentage);
}
}
}
#pragma region Async
void UAsyncLevelLoadSceneComponent::AsyncLevelLoad(const FString& LevelDir, const FString& LevelName)
{
PrimaryComponentTick.bCanEverTick = true;
pLevelDir = LevelDir;
pLevelName = LevelName;
bIsLoading = true;
LoadPackageAsync(LevelDir + LevelName,
FLoadPackageAsyncDelegate::CreateLambda([this, LevelDir, LevelName](const FName& PackageName, UPackage* LoadedPackage, EAsyncLoadingResult::Type Result)
{
if (Result == EAsyncLoadingResult::Succeeded)
{
pResult = Result;
OnLevelLoadedDelegate_Async.Broadcast();
}
}
),
0,
PKG_ContainsMap);
}
void UAsyncLevelLoadSceneComponent::OpenLoadedLevel()
{
FString ResultString = GetLoadingResultString(pResult);
if (pResult != EAsyncLoadingResult::Succeeded)
{
UE_LOG(LogTemp, Error, TEXT("'OpenLoadedLevel' is called, but level is not loaded! | Loading Status: %s"), *ResultString);
return;
}
UE_LOG(LogTemp, Log, TEXT("Level loaded succesful, opening... | Name: %s | Loading Status: %s"), *pLevelName, *ResultString);
UGameplayStatics::OpenLevel(this, FName(*(pLevelDir + pLevelName)));
PrimaryComponentTick.bCanEverTick = false;
}
FString UAsyncLevelLoadSceneComponent::GetLoadingResultString(EAsyncLoadingResult::Type Result)
{
switch (Result)
{
case EAsyncLoadingResult::Succeeded:
return TEXT("Succeeded");
case EAsyncLoadingResult::Failed:
return TEXT("Failed");
case EAsyncLoadingResult::Canceled:
return TEXT("Canceled");
default:
return TEXT("Unknown");
}
}
#pragma endregion
#pragma region Streaming
void UAsyncLevelLoadSceneComponent::StreamLevelLoad(const FString& LevelNameToLoad, const FString& LevelNameToUnload)
{
UE_LOG(LogTemp, Log, TEXT("Loading level: %s"), *LevelNameToLoad);
UE_LOG(LogTemp, Log, TEXT("Will unload level after load: %s"), *LevelNameToUnload);
// Get the name of the current level
pLevelNameToUnload = LevelNameToUnload;
// Load the level with the given name
FLatentActionInfo LatentInfoLoad;
LatentInfoLoad.CallbackTarget = this;
LatentInfoLoad.ExecutionFunction = FName("OnStreamLevelLoaded");
LatentInfoLoad.UUID = 0;
LatentInfoLoad.Linkage = 0;
UGameplayStatics::LoadStreamLevel(this, FName(LevelNameToLoad), true, false, LatentInfoLoad);
}
void UAsyncLevelLoadSceneComponent::OnStreamLevelLoaded()
{
UE_LOG(LogTemp, Log, TEXT("Level loaded. Unloading level: %s"), *pLevelNameToUnload);
OnLevelLoadedDelegate_Streaming.Broadcast();
// Unload the current level
FLatentActionInfo LatentInfoUnload;
UGameplayStatics::UnloadStreamLevel(this, FName(pLevelNameToUnload), LatentInfoUnload, false);
}
#pragma endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment