独立游戏《星尘异变》UE5 C++程序开发日志6——实现存档和基础设置系统

        

目录

一、存档类

1.创建一个SaveGame类

2.存储关卡内数据

3.加载关卡数据

4.关于定时器

5.存储全局数据

6.加载全局数据

二、存档栏

1.存档栏的数据结构

2.创建新存档

3.覆盖已有存档

4.删除存档

三、游戏的基础设置

1.存储游戏设置的数据结构

2.初始化设置

3.修改设置


        本篇日志将会介绍如何实现一个模拟经营游戏中的存档系统以及能够调整游戏画质分辨率等的游戏设置菜单,效果如下图:

一、存档类

1.创建一个SaveGame类

        UE中存档的原理是我们建一个SaveGame类,然后我们在其中声明要存储的变量类型,再实例化一个该类的对象,将要存储的值传给该对象中声明的变量,再调用保存函数就能将数据以.sav文件的方式保存到本地,读档时也是从 该文件中实例化一个SaveGame对象,将该对象中的值赋给当前场景以实现数据的加载

        创建SaveGame类的子类,这里我们已经创建好了两个类,一个存储全局设置包括存档栏,另一个储存关卡数据:

      

2.存储关卡内数据

        每个关卡存档都包含关卡内必须要保存的数据,这里以玩家仓库为例,同时我们每个存档还有记录游玩总时长的功能,FTimeSpan是存储流逝的时间的结构,可以从秒数转化而来:

UCLASS()
class ASTROMUTATE_2_API USaveGameData : public USaveGame
{
	GENERATED_BODY()
public:

	UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="SaveGame")
	FInventoryInformation PlayerStorage;//玩家仓库

	//游戏游玩的总秒数
	UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="Time")
	int PlayedSeconds;

	//游戏游玩的总时间
	UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="Time")
	FTimespan PlayedTime;
};

        接下来就可以实现保存游戏的函数了,首先传入存档的文件名,稍后在加载游戏是也是根据该存档的文件名来找到具体存档,SaveGameSlot中的第一个参数是要保存的SaveGame对象,第二个参数是本地存档文件的名字,第三个参数是玩家的索引,单机游戏使用0即可:

void ADebugActor::SaveGame(const FString& SaveFileName)
{
	UE_LOG(LogTemp,Warning,TEXT("Saving"));
    //实例化我们之前创建的SaveGame类
	USaveGameData* DataToSave{ Cast<USaveGameData>(UGameplayStatics::CreateSaveGameObject(USaveGameData::StaticClass())) };
    //该存档游玩的总秒数=之前读档是继承的总秒数+当前时间-进入游戏时获取的时间
	DataToSave->PlayedSeconds=PlayedSeconds+(FDateTime::Now()-StartTime).GetTotalSeconds();
    //将秒数转换为小时分钟
	DataToSave->PlayedTime=FTimespan::FromSeconds(DataToSave->PlayedSeconds);
	PlayedTime=DataToSave->PlayedTime;
    //从场景中获取玩家库存信息
	SetPlayerStorageEvent();
    //将玩家库存数据赋值给存档类
	DataToSave->PlayerStorage = PlayerStorage;
    //将存档保存到本地
	UGameplayStatics::SaveGameToSlot(DataToSave, SaveFileName, 0);
	UE_LOG(LogTemp,Warning,TEXT("game succesfully saved"));
}

3.加载关卡数据

        在加载存档前,无论是从主菜单加载还是从已经进入的关卡中加载,我们都需要重新打开这个关卡,在打开关卡之后,我们首先需要确保所有关键Actor初始化完成,如果是用c++定义的Actor,可以直接使用DispatchBeginPlay()来确保该actor执行完了BeginPlay中的所有步骤,没有用C++定义的actor比较麻烦,这里的实现方法时进入关卡后设置一个每0.5秒一检查的定时器,所有待加载的Actor都标记为已执行完BeginPlay后,再调用下面的LoadGame函数。

        因为我们实现加载游戏函数的Actor是在关卡内的,所以要实现从主菜单加载,就在玩家点击存档栏中的存档时,将游戏实例中的存档文件名设置成要加载的存档的名字,然后在进入关卡时如果检查到这个文件名不为空,则执行加载。

void ADebugActor::BeginPlay()
{//省略了其他与存档系统无关的代码
	Instance = Cast<UAstromutateGameInstance>(GetWorld()->GetGameInstance());
	if (!Instance->IsValidLowLevel())
	{
		UE_LOG(LogTemp, Error, TEXT("BeginPlay in DebugActor failed,invalid pointer:Instance"));
		return;
	}	
	Super::Begi
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

timidcatt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值