一 UE4的加载模式
在切换关卡时,常常会因为关卡资源过大,造成卡顿,黑屏,那是因为资源过大导致主线程堵塞,引起界面黑屏卡顿,如果使用streamingLevel加载的loading方式,依然无法根本解决线程堵塞问题,这时候就需要用UE4的预加载过程,来开启单独的线程解决这个问题。
二 加载屏幕将具有的所属性的结构FLoadingScreenAttributes
FLoadingScreenAttributes LoadingScreen;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = false;//是否在播放完所有电影并完成加载后,加载屏幕将消失
LoadingScreen.bWaitForManualStop = false;//是否一直播放movies,直到手动停止LoadingScreen.bMoviesAreSkippable = false;//是否加载完成,通过单击加载屏幕来跳过电影
LoadingScreen.MinimumLoadingScreenDisplayTime = 3.0f; // movie最少播放时间
LoadingScreen.PlaybackType = EMoviePlaybackType::MT_Looped;//是否循环
三 代码操作
一、创建C++类,GameInstance
二、在你的项目的Build.cs中加入模块
“HeadMountedDisplay”,
“MoviePlayer”,
“UMG”, “Slate”, “SlateCore”
三、在MyGameInstance.h文件中
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "Runtime/UMG/Public/UMG.h"
#include "Runtime/UMG/Public/UMGStyle.h"
#include "Runtime/UMG/Public/Slate/SObjectWidget.h"
#include "Runtime/UMG/Public/IUMGModule.h"
#include "Runtime/UMG/Public/Blueprint/UserWidget.h"
#include "Runtime/MoviePlayer/Public/MoviePlayer.h"
#include "Runtime/SlateCore/Public/Widgets/SWidget.h"
#include "MyGameInstance.generated.h"
/**
*
*/
UCLASS()
class LOADINGSCREEN_API UMyGameInstance : public UGameInstance
{
GENERATED_BODY()
public:
virtual void Init() override;
UFUNCTION()
virtual void BeginLoadingScreen(const FString& MapName);
UFUNCTION()
virtual void EndLoadingScreen(UWorld* LoadedWorld);
UPROPERTY()
UUserWidget* CurrentWidget;
// loading widget
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UMGGame")
TSubclassOf<UUserWidget> LoadingWidget;
};
四、在MyGameInstance.cpp文件中
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyGameInstance.h"
void UMyGameInstance::Init()
{
Super::Init();
FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &UMyGameInstance::BeginLoadingScreen);
FCoreUObjectDelegates::PostLoadMapWithWorld.AddUObject(this,&UMyGameInstance::EndLoadingScreen);
}
void UMyGameInstance::BeginLoadingScreen(const FString& MapName)
{
FLoadingScreenAttributes LoadingScreen;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = false;//是否在播放完所有电影并完成加载后,加载屏幕将消失
LoadingScreen.bWaitForManualStop = false;//是否一直播放movies,直到手动停止
LoadingScreen.bMoviesAreSkippable = false;//是否加载完成,就可以通过单击加载屏幕来跳过电影
LoadingScreen.MinimumLoadingScreenDisplayTime = 3.0f; // movie最少播放时间
//LoadingScreen.PlaybackType = EMoviePlaybackType::MT_Looped;
LoadingScreen.WidgetLoadingScreen = FLoadingScreenAttributes::NewTestLoadingScreenWidget(); // movie不存在时,显示的widget
if (LoadingWidget != nullptr)
{
CurrentWidget = CreateWidget<UUserWidget>(this, LoadingWidget);
TSharedPtr<SWidget> LoadScreen = CurrentWidget->TakeWidget();
LoadingScreen.WidgetLoadingScreen = LoadScreen;
}
else
{
UE_LOG(LogTemp, Warning, TEXT("LoadingWidget == nullptr"));
}
//LoadingScreen.MoviePaths.Add("squad_intro_movie");
GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
}
void UMyGameInstance::EndLoadingScreen(UWorld* LoadedWorld)
{
UE_LOG(LogTemp,Warning,TEXT("LoadSuccess"));
GetMoviePlayer()->StopMovie();
}
五、在蓝图中设置一下项目设置,创建Gameinstance 蓝图
设置
六、创建widget,作为GameInstance 中为加载widget
最后编译运行即可:
参考官方文档:
https://docs.unrealengine.com/5.0/en-US/API/Runtime/MoviePlayer/FLoadingScreenAttributes/