Download

Trying to play a level sequence after play a movie - possible thread issue?

First, I have to say, I’m not sure I’m posting this thread in the right place because I still not sure what is causing my issue. Since there is code involved, I thing this may be the best section for this.

So, my game have a few cutscenes that plays a movie .mp4 file (the movie is rendered in a UMG overlay) and then, after the movie reaches the end, a level sequence continues the cutscene, now in real time.

The problem is, there is a small gap between then: when the movie ends, I can see, for just a fraction of second, a frame with the wrong camera angle and the objects in the wrong position. It seems that there is a delay before the level sequence actually start.

This is the code that plays the movie:



MoviePlayer->OnEndReached.AddDynamic(this, &ACutscene::OnMovieEnded);
MoviePlayer->Play();
ShowMovieOnScreen(); // here the UMG widget is added to the viewport. I'm omitting this part because the implementation contains some blueprint code and events, but it is pretty straightforward


And here is the OnMovieEnded, called when the movie reaches the end:



void ACutscene::OnMovieEnded()
{
  HideMovieOnScreen(); // Similar to ShowMovieOnScreen, but here the UMG widget is removed from the viewport
  Sequence->SequencePlayer->Play();
}


Everything works almost fine, except this small delay before the sequence actually play.

My theory: there is no delay in the playback, and the delay is actually in the render thread. I think the UMG widget is being removed immediately, while the first frame of the level sequence will only be rendered after that small delay.

May my theory be correct? If so, what can I do to avoid this issue? I think a good idea would be to “prepare” the level sequence to put everything “in place” as soon the movie playback start - setup the camera’s transform and object’s transforms as they are expected in the first frame, enable the cinematic mode and stuff like that. But I don’t know if there is an easy way to do this (maybe a play() followed by a Pause() would be enough, but I’m afraid it can fire events and cause weird and unexpected behaviors).

If you have any idea that can fix this issue, I would be glad to hear, thank you.

So, in case someone has a similar problem, of course it was not a thread issue, it happens even if I render the movie in a plane placed in the world. The issue happened only because I hide the movie from the screen, call Play() in the sequence, but the first tick of the sequence happens only in the next frame (the ALevelSequenceActor basically calls a function named Update() in the tick function, if it’s not paused).

I fixed the problem with this piece of code, called when the movie starts it’s playback:

Sequence->SequencePlayer->Play();
Sequence->SequencePlayer->Update(0.f);
Sequence->SequencePlayer->Pause();

And that’s it. It basically forces the update of one frame of the sequence and then holds it, waiting until the movie finishes the playback. It’s not perfect, I think it may have issues if using event tracks (or even sound FXs), but it is not my case.

1 Like