游戏开头影片播放
游戏开头可以添加 开始的视频,用以等待游戏的第一个关卡的加载。
在项目的Movies中设置
wait for Movies to Complete 勾选时,是指即便关卡加载完成。影片仍然播放直到结束。
Moies Are Skippable 勾选室,是指当关卡加载完成后,如果影片还在播放。那么可以点击屏幕结束影片播放。
Startup Movies 是所需要播放的视频,为了兼容所有平台,我们使用mp4格式的视频。 所有视频必须是位于/Game/Movies/ 中。名字就是文件的名称。
如果Startup Moives 是空的,那么默认Startup Movies 中有一个名为Default_Startup的视频, 如果/Game/Movies/ 中刚好有这个视频,就会在开始时自动播放。
loading界面,全屏影片播放
FDefaultGameMoviePlayer 是一个用于播放视频和加载界面的一个类。引擎中有一个实例,通过 GetMoviePlayer()函数获取
用于视频播放:
当我们播放视频时,主要用到了这几个函数
virtual bool PlayMovie() override;
virtual void StopMovie() override;
virtual void SetupLoadingScreen(const FLoadingScreenAttributes& LoadingScreenAttributes) override;
FLoadingScreenAttributes控制了加载界面的属性。
主要属性包括:
字段 |
类型 |
默认值 |
作用 |
WidgetLoadingScreen |
TSharedPtr<class SWidget> |
NULL |
加载时显示的UI。显示于视频之上或者没有视频时单独显示 |
MoviePaths |
TArray<FString> |
空 |
用于播放的视频列表,视频应位于/Game/Movies文件夹下 |
MinimumLoadingScreenDisplayTime |
float |
-1.0f |
加载界面显示的最短时间(优先级高于bAutoCompleteWhenLoadingCompletes),如果大于0,在时间未到之前,GetMoviePlayer()->IsLoadingFinished()都将返回false。 |
bAutoCompleteWhenLoadingCompletes |
bool |
true |
当加载完成后,加载界面是否自动消失(如果MinimumLoadingScreenDisplayTime小于0,没有影片时,不管该参数是否是true,加载完成都会自动消失) |
bMoviesAreSkippable |
bool |
true |
当加载完成后,如果点击屏幕,是否跳过加载界面 |
PlaybackType |
TEnumAsByte<EMoviePlaybackType> |
EMoviePlaybackType::MT_Normal |
视频播放的循环方式 |
播放代码如下 。同时需要在你的模块构建文件中加入"MoviePlayer", "UMG" 这两个模块
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject","Engine", "InputCore","MoviePlayer","UMG"});
#include "MoviePlayer/Public/MoviePlayer.h"
#include "Runtime/UMG/Public/Blueprint/UserWidget.h"
bool UMyBlueprintFunctionLibrary::PlayMovie(UUserWidget * widgetTemplate, TArray<FString> Names, bool bSkippable)
{
if (Names.Num() > 0) {
FLoadingScreenAttributes LoadingScreen;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = false;//因为我们没有在加载关卡,所以这个需要设置为false,不然视频一播放就停止了
LoadingScreen.bMoviesAreSkippable = bSkippable;
LoadingScreen.MoviePaths = Names;
if (widgetTemplate) {
LoadingScreen.WidgetLoadingScreen = widgetTemplate->TakeWidget();
}
GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
return GetMoviePlayer()->PlayMovie();
}
else {
return true;
}
}
void UMyBlueprintFunctionLibrary::stopMovie()
{
GetMoviePlayer()->StopMovie();
}
用于加载关卡的loading界面:
在调用openLevel时,UEngine::LoadMap 将被调用来加载关卡。该函数将一直堵塞游戏进程直到所有内容加载结束。在该函数中,会调用
FCoreUObjectDelegates::PreLoadMap.Broadcast(URL.Map) 来表示关卡开始加载。
FCoreUObjectDelegates::PostLoadMapWithWorld.Broadcast(WorldContext.World());表示已成功加载关卡
不过该函数中并没有关于加载进度的信息,如果需要加载进度,需要自行修改UEngine::LoadMap中的代码。
GEngineLoop.PreInit阶段,FDefaultGameMoviePlayer的Initialize函数被调用。
在Initialize函数中,加入了关卡开始加载时,调用的函数FDefaultGameMoviePlayer::OnPreLoadMap。 (FCoreUObjectDelegates::PreLoadMap.AddRaw( this, &FDefaultGameMoviePlayer::OnPreLoadMap );)
OnPreLoadMap中,将调用PlayMovie播放上一次通过SetupLoadingScreen设置的FLoadingScreenAttributes中的视频和UI,并使用其中的播放设置,如果播放成功的话将加入关卡加载结束时调用的函数OnPostLoadMap。
(FCoreUObjectDelegates::PostLoadMapWithWorld.AddRaw(this, &FDefaultGameMoviePlayer::OnPostLoadMap );)
OnPostLoadMap函数。将调用WaitForMovieToFinish(); 该函数根据我们设置的播放属性,决定是否继续等待视频播放,还是自动结束。并通过FLoadingScreenAttributes的默认值,设置FDefaultGameMoviePlayer的播放属性。
要在关卡加载时,根据不同map显示不同的加载界面,
一种方法是在调用openLevel之前,通过GetMoviePlayer()->SetupLoadingScreen(LoadingScreen) 来设置 显示的加载界面。
另外一种就是设置我们自己关于FCoreUObjectDelegates::PreLoadMap的监听事件,在监听事件中通过GetMoviePlayer()->SetupLoadingScreen(LoadingScreen)设置。在监听函数中,MapName作为参数被传进来
下面是在openLevel之前设置的过程:
头文件中:
UCLASS()
class TESTOPENMOVIE_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
UFUNCTION(BlueprintCallable, Category = "loadingScene", meta=(AdvancedDisplay = "MovieNames,bSkippable,bAutoCompleteWhenLoadingCompletes", AutoCreateRefTerm = "MovieNames"))
static void SetLoadSceneAttributes(UUserWidget * widgetTemplate, const TArray
UFUNCTION(BlueprintCallable, Category = "loadingScene")
static bool IsLoadingFinished();
};
cpp中:
void UMyBlueprintFunctionLibrary::SetLoadSceneAttributes(UUserWidget * widgetTemplate, const TArray
{
FLoadingScreenAttributes LoadingScreen;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = bAutoCompleteWhenLoadingCompletes;
LoadingScreen.bMoviesAreSkippable = bSkippable;
LoadingScreen.MoviePaths = MovieNames;
if (widgetTemplate) {
LoadingScreen.WidgetLoadingScreen = widgetTemplate->TakeWidget();
}
GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
}
bool UMyBlueprintFunctionLibrary::IsLoadingFinished()
{
return GetMoviePlayer()->IsLoadingFinished();
}
蓝图中:
加载界面中,我们用文本来显示是否加载成功。绑定文本属性如下:
下面是设置监听事件的方法:
通常我们需要一个游戏期间一直存在的对象来设置我们自己的PreLoadMap监听事件。所以我们可以在这里可以用一下GameInstance。
在我们自己的GameIntance的Init函数中。我们可以设置如下的监听
FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &UMyGameInstance::OnPreLoadMap);
在该监听函数中,我们可以设置自己的加载界面,播放的视频,播放属性等。
因为Broadcast的分发采用的是倒序的。我们的监听事件先执行,而FDefaultGameMoviePlayer::OnPreLoadMap 后执行,我们在自己监听事件中设置的GetMoviePlayer()->SetupLoadingScreen(LoadingScreen)就会被用作为最新的播放属性。
代码如下:
void UMyGameInstance::Init()
{
Super::Init();
FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &UMyGameInstance::BeginLoadMap);
FCoreUObjectDelegates::PostLoadMapWithWorld.AddUObject(this, &UMyGameInstance::EndLoadMap);
}
void UMyGameInstance::BeginLoadMap(const FString& map)
{
UE_LOG(LogTemp, Log, TEXT("beginloadMap"));
loadNum++;
if (loadNum == 1) return;
FLoadingScreenAttributes LoadingScreen;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = false;
LoadingScreen.bMoviesAreSkippable = true;
LoadingScreen.PlaybackType = EMoviePlaybackType::MT_Looped;
LoadingScreen.MoviePaths.Add("LoadingScreen");
LoadingScreen.WidgetLoadingScreen = FLoadingScreenAttributes::NewTestLoadingScreenWidget();
GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
}
void UMyGameInstance::EndLoadMap(UWorld* map)
{
UE_LOG(LogTemp, Log, TEXT("endloadMap"));
}
上面有一个if (loadNum == 1) return; 这里我们是用来区分是否是第一个关卡,如果是,则我们不应该设置FLoadingScreenAttributes,因为如果是第一个关卡在加载,我们设置了新的FLoadingScreenAttributes,则我们在 项目的Movies中设置的 控制选项就会被新的设置取代。