unreal engine异步加载关卡参考笔记
2023-08-02 本文已影响0人
吉凶以情迁
第一种:
创建一个c++游戏 实例然后蓝图继承,然后设置widget 就行,缺点:测试不能加载widget动画
void ULoadScreenGameInstance::Init()
{
Super::Init();
FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &ULoadScreenGameInstance::BeginLoadingScreen);
FCoreUObjectDelegates::PostLoadMapWithWorld.AddUObject(this, &ULoadScreenGameInstance::EndLoadingScreen);
}
void ULoadScreenGameInstance::BeginLoadingScreen(const FString& MapName)
{
FLoadingScreenAttributes LoadingScreen;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = false; //在播放完所有电影并完成加载后,加载屏幕将消失
LoadingScreen.bWaitForManualStop = false; //一直播放movies,除非直到手动停止
LoadingScreen.bMoviesAreSkippable = false; //加载完成后是否允许通过单击加载屏幕来跳过电影
LoadingScreen.MinimumLoadingScreenDisplayTime = 2.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;
OnLoadingWidgetSuccess(CurrentWidget);
UE_LOG(LogTemp, Warning, TEXT("LoadWidgetSuccess"));
}
else
{
UE_LOG(LogTemp, Warning, TEXT("LoadingWidget == nullptr"));
}
//LoadingScreen.MoviePaths.Add("squad_intro_movie");
GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
}
void ULoadScreenGameInstance::EndLoadingScreen_Implementation(UWorld* LoadedWorld)
{
UE_LOG(LogTemp, Warning, TEXT("LoadSuccess"));
GetMoviePlayer()->StopMovie();
}
第二种
b站视频老外的,则需要调整一个配置,打开uproject文件 修改LoadingPhase
为具体啥来着,参考视频 ,或者搜索关键词
{
"FileVersion": 3,
"EngineAssociation": "5.2",
"Category": "",
"Description": "",
"Modules": [
{
"Name": "CppDigitalTwn",
"Type": "Runtime",
"LoadingPhase": "Default",
老外的代码
#include "ActionRPGLoadingScreen.h"
#include "SlateBasics.h"
#include "SlateExtras.h"
#include "MoviePlayer.h"
#include "SThrobber.h"
// This module must be loaded "PreLoadingScreen" in the .uproject file, otherwise it will not hook in time!
struct FRPGLoadingScreenBrush : public FSlateDynamicImageBrush, public FGCObject
{
FRPGLoadingScreenBrush(const FName InTextureName, const FVector2D& InImageSize)
: FSlateDynamicImageBrush(InTextureName, InImageSize)
{
SetResourceObject(LoadObject<UObject>(NULL, *InTextureName.ToString()));
}
virtual void AddReferencedObjects(FReferenceCollector& Collector)
{
if (UObject* CachedResourceObject = GetResourceObject())
{
Collector.AddReferencedObject(CachedResourceObject);
}
}
};
class SRPGLoadingScreen : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SRPGLoadingScreen) {}
SLATE_END_ARGS()
void Construct(const FArguments& InArgs)
{
// Load version of the logo with text baked in, path is hardcoded because this loads very early in startup
static const FName LoadingScreenName(TEXT("/Game/UI/T_ActionRPG_TransparentLogo.T_ActionRPG_TransparentLogo"));
LoadingScreenBrush = MakeShareable(new FRPGLoadingScreenBrush(LoadingScreenName, FVector2D(1024, 256)));
FSlateBrush *BGBrush = new FSlateBrush();
BGBrush->TintColor = FLinearColor(0.034f, 0.034f, 0.034f, 1.0f);
ChildSlot
[
SNew(SOverlay)
+ SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SBorder)
.BorderImage(BGBrush)
]
+SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(SImage)
.Image(LoadingScreenBrush.Get())
]
+SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SVerticalBox)
+SVerticalBox::Slot()
.VAlign(VAlign_Bottom)
.HAlign(HAlign_Right)
.Padding(FMargin(10.0f))
[
SNew(SThrobber)
.Visibility(this, &SRPGLoadingScreen::GetLoadIndicatorVisibility)
]
]
];
}
private:
/** Rather to show the ... indicator */
EVisibility GetLoadIndicatorVisibility() const
{
bool Vis = GetMoviePlayer()->IsLoadingFinished();
return GetMoviePlayer()->IsLoadingFinished() ? EVisibility::Collapsed : EVisibility::Visible;
}
/** Loading screen image brush */
TSharedPtr<FSlateDynamicImageBrush> LoadingScreenBrush;
};
class FActionRPGLoadingScreenModule : public IActionRPGLoadingScreenModule
{
public:
virtual void StartupModule() override
{
// Force load for cooker reference
LoadObject<UObject>(nullptr, TEXT("/Game/UI/T_ActionRPG_TransparentLogo.T_ActionRPG_TransparentLogo") );
if (IsMoviePlayerEnabled())
{
CreateScreen();
}
}
virtual bool IsGameModule() const override
{
return true;
}
virtual void StartInGameLoadingScreen(bool bPlayUntilStopped, float PlayTime) override
{
FLoadingScreenAttributes LoadingScreen;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = !bPlayUntilStopped;
LoadingScreen.bWaitForManualStop = bPlayUntilStopped;
LoadingScreen.bAllowEngineTick = bPlayUntilStopped;
LoadingScreen.MinimumLoadingScreenDisplayTime = PlayTime;
LoadingScreen.WidgetLoadingScreen = SNew(SRPGLoadingScreen);
GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
}
virtual void StopInGameLoadingScreen() override
{
GetMoviePlayer()->StopMovie();
}
virtual void CreateScreen()
{
FLoadingScreenAttributes LoadingScreen;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = true;
LoadingScreen.MinimumLoadingScreenDisplayTime = 3.f;
LoadingScreen.WidgetLoadingScreen = SNew(SRPGLoadingScreen);
GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
}
};
IMPLEMENT_GAME_MODULE(FActionRPGLoadingScreenModule, ActionRPGLoadingScreen);
然后通过纯蓝图c++代码 调用它
URPGBlueprintLibrary::URPGBlueprintLibrary(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
void URPGBlueprintLibrary::PlayLoadingScreen(bool bPlayUntilStopped, float PlayTime)
{
IActionRPGLoadingScreenModule& LoadingScreenModule = IActionRPGLoadingScreenModule::Get();
LoadingScreenModule.StartInGameLoadingScreen(bPlayUntilStopped, PlayTime);
}
void URPGBlueprintLibrary::StopLoadingScreen()
{
IActionRPGLoadingScreenModule& LoadingScreenModule = IActionRPGLoadingScreenModule::Get();
LoadingScreenModule.StopInGameLoadingScreen();
}
另外也提到了转移地图
![](https://img.haomeiwen.com/i2815884/e2e7efccb2a3ef49.png)
需要注意的是,要测试则应该使用editr- stand mode
经过测试自己整的widget播放动画没效果,实际应该没问题,设置循环播放也看不到在动
https://www.bilibili.com/video/BV1R7411L7BR/
https://github.com/truong-bui/AsyncLoadingScreen
https://github.com/larrynow/ActionRPG
https://blog.csdn.net/u010385624/article/details/90044368
https://blog.csdn.net/qq_43021038/article/details/125309958
运作模式应该有3种方法?,一种是监听PreLoadMap
还有一种同时改配置文件,只需要在game 游戏实例中调用就行。