SeamTravel可以保存数据,但如果再TravelMap里放上加载界面效果极差,又希望把加载功能尽量做小且可以使用UMG,所以不使用AsyncLoadSystem,异步线程太麻烦。结合网络文章写了一个简单测试版。
零、主要思想
0.1、通过GameInstance的PreLoad广播+PostLoad广播实现界面自动创建与销毁
0.2、使用中的MoviePlayer实现UMG在Slate线程显示加载界面,而不再被主线程阻塞
0.3、只完成最简单的加载界面逻辑,且尽量描述啰嗦
0.4、 参考文档
CSDN
https://www.cnblogs.com/wzj998/p/7066657.html
官方视频,介绍了MoviePlayer和SeamTravel
https://www.bilibili.com/video/BV1XE41147dQ
一、前期准备
1.1、必要模块加载
1.2、自己创建一个C++的GameInstance
二、c++部分代码
2.1、.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "MyGameInstance.generated.h"
class UUserWidget;
/**
*
*/
UCLASS()
class HMXX_01_API UMyGameInstance : public UGameInstance
{
GENERATED_BODY()
public:
UMyGameInstance();
//主要任务是绑定关卡加载前后的广播,用于自动执行BeginLoad和EndLoad
virtual void Init() override;
//显示加载屏幕
UFUNCTION()
virtual void BeginLoadingScreen(const FString& MapName);
//隐藏加载屏幕
UFUNCTION()
virtual void EndLoadingScreen(UWorld* LoadedWorld);
protected:
//加载界面的类,蓝图中自定义
UPROPERTY(EditDefaultsOnly)
TSubclassOf<UUserWidget> LoadingWidgetClass;
//加载界面指针
UPROPERTY()
UUserWidget* LoadingWidget;
};
2.2 .cpp
#include "MyGameInstance.h"
#include "Blueprint/UserWidget.h"
#include "Runtime/MoviePlayer/Public/MoviePlayer.h"
UMyGameInstance::UMyGameInstance()
:Super(),LoadingWidgetClass(nullptr),LoadingWidget(nullptr)
{
}
void UMyGameInstance::Init()
{
Super::Init();
//直接绑定地图加载前后的广播事件
FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &UMyGameInstance::BeginLoadingScreen);
FCoreUObjectDelegates::PostLoadMapWithWorld.AddUObject(this, &UMyGameInstance::EndLoadingScreen);
}
void UMyGameInstance::BeginLoadingScreen(const FString& MapName)
{
UE_LOG(LogTemp, Log, TEXT("BeginLoadingScreen"));
//如果当前不是独立服务器的话,单机游戏可以忽略该判断
if (!IsRunningDedicatedServer())
{
//这是UE4自带的加载屏幕类型
FLoadingScreenAttributes LoadingScreen;
//对其进行属性配置
//当加载完成时是否自动结束播放
LoadingScreen.bAutoCompleteWhenLoadingCompletes = true;
//添加我们的UMG
//根据Class创建我们的UMG
LoadingWidget = CreateWidget<UUserWidget>(this, LoadingWidgetClass);
//获取到UMG对应的共享指针
TSharedPtr<SWidget> WidgetPtr = LoadingWidget->TakeWidget();
//正式设置
LoadingScreen.WidgetLoadingScreen = WidgetPtr;
// 播放影片相关,我没用到
// 如果加载完成是否可以任意键打断影片播放
//LoadingScreen.bMoviesAreSkippable = false;
// 等待到影片播放结束
//LoadingScreen.bWaitForManualStop = true;
// 视频播放类型
//LoadingScreen.PlaybackType = EMoviePlaybackType::MT_Looped;
// 视频播放路径
// 下方路径对应:Content\Movies目录下的squad_intro_movie.mp4文件
//LoadingScreen.MoviePaths.Add("squad_intro_movie");
//放MovePlayer里播放
GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
}
}
void UMyGameInstance::EndLoadingScreen(UWorld* LoadedWorld)
{
UE_LOG(LogTemp, Log, TEXT("EndLoadingScreen"));
//删除UMG
if (!IsRunningDedicatedServer())
{
if (LoadingWidget)
{
//从父组件移除
LoadingWidget->RemoveFromParent();
//标记删除
LoadingWidget->MarkPendingKill();
}
}
}
三、创建自己的UMG
3.1、简易UMG
3.2基于MyGameInstance创建的蓝图,配置UMG,并在Editor选项卡下将GameInstance设置为该蓝图
四、以独立窗口方式运行,直接出效果。
!!!注意: 编辑器模式下运行不会出效果