天天看点

UE4 C++ 使用GameInstance实现简单加载界面调用零、主要思想一、前期准备二、c++部分代码三、创建自己的UMG四、以独立窗口方式运行,直接出效果。

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、必要模块加载
UE4 C++ 使用GameInstance实现简单加载界面调用零、主要思想一、前期准备二、c++部分代码三、创建自己的UMG四、以独立窗口方式运行,直接出效果。

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

UE4 C++ 使用GameInstance实现简单加载界面调用零、主要思想一、前期准备二、c++部分代码三、创建自己的UMG四、以独立窗口方式运行,直接出效果。

3.2基于MyGameInstance创建的蓝图,配置UMG,并在Editor选项卡下将GameInstance设置为该蓝图

UE4 C++ 使用GameInstance实现简单加载界面调用零、主要思想一、前期准备二、c++部分代码三、创建自己的UMG四、以独立窗口方式运行,直接出效果。

四、以独立窗口方式运行,直接出效果。

!!!注意: 编辑器模式下运行不会出效果

UE4 C++ 使用GameInstance实现简单加载界面调用零、主要思想一、前期准备二、c++部分代码三、创建自己的UMG四、以独立窗口方式运行,直接出效果。

继续阅读