Quick answer: Register the loading screen in response to the PreLoadMap delegate (before the map opens). It auto-dismisses on PostLoadMapWithWorld — don’t hold it open with a manual flag.

An async loading screen shows during a level transition but never goes away — the player is stuck staring at it after the new level is already running.

Hook the Map Delegates

void FMyLoadingScreenModule::StartupModule()
{
    FCoreUObjectDelegates::PreLoadMap.AddRaw(this, &FMyLoadingScreenModule::OnPreLoadMap);
    FCoreUObjectDelegates::PostLoadMapWithWorld.AddRaw(this, &FMyLoadingScreenModule::OnPostLoadMap);
}

void FMyLoadingScreenModule::OnPreLoadMap(const FString&)
{
    RegisterLoadingScreen();   // BEFORE the map starts loading
}

Registering in PreLoadMap is the key — register after OpenLevel and the screen comes up late and the dismissal timing breaks.

Let the MoviePlayer Auto-Dismiss

With FLoadingScreenAttributes and the standard MoviePlayer, the engine dismisses the screen automatically once the new world is ready. Don’t add a manual “keep open until I say so” flag unless you genuinely need extra time — a flag that never clears is the usual stuck-screen cause.

bAutoCompleteWhenLoadingCompletes

Set this true in the loading screen attributes so the screen ends as soon as loading finishes. If false, you must explicitly stop it — and forgetting to is exactly the bug.

Minimum Display Time

Use MinimumLoadingScreenDisplayTime for a floor (so fast loads don’t flash). That’s the legitimate way to “hold” it — not a manual flag.

Verifying

Transition between levels repeatedly. The loading screen appears before the load and dismisses right as the new level becomes playable. Fast loads still show it briefly, not forever.

“Register on PreLoadMap, auto-complete on load. Manual ‘keep open’ flags are how screens get stuck.”

If you need a ‘press any key to continue’ after load, that’s a separate UMG screen — don’t repurpose the engine loading screen for it.