Game Movie Player: black screen when loading is finished

I’m using the Game Movie Player to display a loading screen while async loading the next level. I’m not playing a movie, but using a widget overlay instead.

When using these FLoadingScreenAttributes settings:

loading_screen.bAutoCompleteWhenLoadingCompletes = true;
loading_screen.bWaitForManualStop = false;
loading_screen.bAllowEngineTick = true;
loading_screen.MinimumLoadingScreenDisplayTime = -1;
loading_screen.WidgetLoadingScreen = LoadingScreenWidget->TakeWidget();

everything works fine, smooth transition from widget to next level.

However, as soon as bAutoCompleteWhenLoadingCompletes is set to false (to specify a MinimumLoadingScreenDisplayTime or to use bWaitForManualStop) the screen turns black as soon as the level is loaded until the loading screen closes.

The behavior of the movieplayer is as expected in those cases (black screen ends after x seconds or after user input) and OnMoviePlaybackFinished is only broadcasted at the end of the black screen.

What’s not expected is that the widget is not displayed anymore after the level is finished loading.

I have not tested this issue yet with movies, so I don’t know if it’s only happening with overlay widgets.

Same for me. I do it like this:

void UGH_LoadingScreenSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
	Super::Initialize(Collection);

	FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &ThisClass::BeginLoadingScreen);
}

void UGH_LoadingScreenSubsystem::BeginLoadingScreen(const FString& String)
{
	FLoadingScreenAttributes LoadingScreen;
	LoadingScreen.bAutoCompleteWhenLoadingCompletes = false;
	LoadingScreen.PlaybackType = EMoviePlaybackType::MT_Looped;
	LoadingScreen.WidgetLoadingScreen = FLoadingScreenAttributes::NewTestLoadingScreenWidget();
	LoadingScreen.MoviePaths.Add("UE4_Startup_Moving_Logo_4K_60");
	LoadingScreen.MoviePaths.Add("Logo sample");

	IGameMoviePlayer* MoviePlayer = GetMoviePlayer();
	MoviePlayer->SetupLoadingScreen(LoadingScreen);
	MoviePlayer->PlayMovie();
}

The movies are looping until I hit a key, but the widget is disappearing.

If I unterstand the code correctly, the test widget should actually remove the throbber widget and display a “Loading completed!” text instead once loading has finished. However I did not yet understand what “completely loaded” means in this context. Who is telling the movie player that loading has finished?

I fixed it by applying the following patch to the engine (5.0.3 source build). Seems like a bug to me!?

Index: Engine/Source/Runtime/MoviePlayer/Private/DefaultGameMoviePlayer.cpp
===================================================================
diff --git a/Engine/Source/Runtime/MoviePlayer/Private/DefaultGameMoviePlayer.cpp b/Engine/Source/Runtime/MoviePlayer/Private/DefaultGameMoviePlayer.cpp
--- a/Engine/Source/Runtime/MoviePlayer/Private/DefaultGameMoviePlayer.cpp	(revision 0b0bcb3adfabea95f9a061a430c0f7c5cbedf70c)
+++ b/Engine/Source/Runtime/MoviePlayer/Private/DefaultGameMoviePlayer.cpp	(date 1664976414824)
@@ -465,14 +465,7 @@
             // Transfer the content to the main window
             MainWindow.Pin()->SetContent(LoadingScreenContents.ToSharedRef());
         }
-        if (VirtualRenderWindow.IsValid())
-        {
-            VirtualRenderWindow->SetContent(SNullWidget::NullWidget);
-        }
-		if (UserWidgetHolder.IsValid())
-		{
-			UserWidgetHolder->SetContent(SNullWidget::NullWidget);
-		}
+        
 
 		const bool bAutoCompleteWhenLoadingCompletes = LoadingScreenAttributes.bAutoCompleteWhenLoadingCompletes;
 		const bool bWaitForManualStop = LoadingScreenAttributes.bWaitForManualStop;
@@ -572,6 +565,15 @@
 			}
 		}
 
+		if (VirtualRenderWindow.IsValid())
+		{
+			VirtualRenderWindow->SetContent(SNullWidget::NullWidget);
+		}
+		if (UserWidgetHolder.IsValid())
+		{
+			UserWidgetHolder->SetContent(SNullWidget::NullWidget);
+		}
+
 		LoadingIsDone.Set(1);
 		IsMoviePlaying = false;
 		FCoreDelegates::OnAsyncLoadingFlushUpdate.Remove(OnAsyncLoadingFlushUpdateDelegateHandle);

Thanks for confirming this is indeed an issue.
At the moment we’re not using a source build (and setup would require some time we can’t afford right now).

I just hope Epic releases a fix in a next update on the engine.

Yes. Seems to be fixed in 5.1 https://github.com/EpicGames/UnrealEngine/commit/833a1966f7b96c15dbf2aff7a029476fde06edc4

1 Like

Awesome, thanks for looking that up!

Has anyone managed to make this loading screen work with bWaitForManualStop = true in 5.1? I’m trying to make the loading screen to stay longer (until some other actors are spawned in level), but then it’s stuck for ever. MoviePlayer->StopMovie() seems to be ignored and doesn’t close the screen.

I also have problems (GPU hang) with running bWaitForManualStop = true, but only on consoles (XSX and PS5). On PC builds this isn’t an issue. We are using 5.2 at the moment. If anyone has managed to make it work please let us know!

Sorry to necro this, but I don’t suppose you ever got this working?

Edit: Of course shortly after posting this I managed to figure out the issue I was having, so incase someone comes across this in the future:
StopMovie() must be called from the Slate thread, or LoadingScreen.bAllowEngineTick must be true, otherwise it’s not actually called since the main thread is blocked while the movie is playing, even if loading is done.