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設定為該藍圖
四、以獨立視窗方式運作,直接出效果。
!!!注意: 編輯器模式下運作不會出效果