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();
}

另外也提到了转移地图


image.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 游戏实例中调用就行。

上一篇 下一篇

猜你喜欢

热点阅读