保存和加载游戏
蓝图实现
创建SaveGame对象

在新的 SaveGame 对象蓝图中,创建要保存所有信息的变量。

保存游戏
首先,使用 Create Save Game Object 节点,基于 SaveGame 类创建对象。

给 Save Game 实例中的 PlayerName 变量赋值。

完成 SaveGame 对象的赋值之后,利用 Save Game To Slot 节点完成保存游戏。
SlotName 为文件名,UserIndex 为用户 ID 。

保存游戏文件使用 .sav 扩展名,并在项目的 Saved\SaveGames 文件夹中显示。

加载游戏
要加载保存的游戏,需要提供保存时使用的插槽名和用户ID。
如果存在指定 SaveGame ,引擎将用其中数据填充 SaveGame 对象,并将其返回为 SaveGame(USaveGame类)基本对象。
然后可将该对象转换为自定义 SaveGame 类并访问数据。

异步方法
若有大量数据,或希望在加载时使用加载画面或动画,建议采用异步方法。同步方法主要用于快速加载小型数据。

Async Load Game From Slot 和 Async Save Game to Slot 节点具有两个执行输出引脚。
操作开始时将执行第一个引脚,操作完成时则执行第二个引脚,执行第二引脚前变量输出引脚无效。
Success 引脚可表示操作是否成功。
C++实现
创建SaveGame对象

MySaveGame.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/SaveGame.h"
#include "MySaveGame.generated.h"
/**
*
*/
UCLASS()
class SAVEANDLOADGAME_API UMySaveGame : public USaveGame
{
GENERATED_BODY()
public:
UPROPERTY(VisibleAnywhere, Category = Basic)
FString PlayerName;
};
保存游戏
异步保存
推荐使用 AsyncSaveGameToSlot 保存游戏。使用异步可防止帧率突然卡帧,使玩家不易觉察,并避免某些平台上出现认证问题。
if (UMySaveGame* SaveGameInstance = Cast<UMySaveGame>(UGameplayStatics::CreateSaveGameObject(UMySaveGame::StaticClass())))
{
//设置委托
FAsyncSaveGameToSlotDelegate SaveDelegate;
//设置SaveGame对象上的数据
SaveGameInstance->PlayerName = TEXT("AsyncPlayer");
//启动异步保存进程
UGameplayStatics::AsyncSaveGameToSlot(SaveGameInstance, TEXT("AsyncCPPSave"), 0, SaveDelegate);
UE_LOG(LogTemp, Warning, TEXT("AsyncSave Success"));
}
同步保存
SaveGameToSlot 足以应对小型SaveGame格式,暂停时或在菜单中即可保存游戏。
if (UMySaveGame* SaveGameInstance = Cast<UMySaveGame>(UGameplayStatics::CreateSaveGameObject(UMySaveGame::StaticClass())))
{
//设置SaveGame对象上的数据
SaveGameInstance->PlayerName = TEXT("SyncPlayer");
//保存游戏
if (UGameplayStatics::SaveGameToSlot(SaveGameInstance, TEXT("SyncCPPSave"), 0))
{
//成功保存
UE_LOG(LogTemp, Warning, TEXT("SyncSave Success"));
}
}
二进制保存
SaveGameToMemory 函数将 SaveGame 对象传输到内存,函数仅支持同步操作,但快于保存到驱动器。
函数调用将提供存储数据缓冲区(TArray&)的引用。
成功时,函数返回true。
TArray<uint8> SaveData;
UMySaveGame* SaveGameInstance = Cast<UMySaveGame>(UGameplayStatics::CreateSaveGameObject(UMySaveGame::StaticClass()));
SaveGameInstance->PlayerName = TEXT("BinaryPlayer");
if (UGameplayStatics::SaveGameToMemory(SaveGameInstance, SaveData))
{
// 操作成功,SaveData现在包含SaveGame对象的二进制代表。
if (UGameplayStatics::SaveDataToSlot(SaveData, TEXT("BinaryCPPSave"), 0))
{
// 操作成功,已将SaveData写入到存档文件。
UE_LOG(LogTemp, Warning, TEXT("BinarySave Success"));
}
}
加载游戏
异步加载
AsyncLoadGameFromSlot 执行异步加载时,必须提供回调委托,以接收系统加载的数据。
//设置委托
FAsyncLoadGameFromSlotDelegate LoadedDelegate;
LoadedDelegate.BindUObject(this, &ABasePlayer::LoadGameDelegateFunction);
UGameplayStatics::AsyncLoadGameFromSlot(TEXT("AsyncCPPSave"), 0, LoadedDelegate);
同步加载
若成功,LoadGameFromSlot 函数将创建并返回 USaveGame 对象。
//查找并将USaveGame对象转换成UMySaveGame
if (UMySaveGame* LoadedGame = Cast<UMySaveGame>(UGameplayStatics::LoadGameFromSlot(TEXT("SyncCPPSave"), 0)))
{
UE_LOG(LogTemp, Warning, TEXT("SyncLoad: %s"), *LoadedGame->PlayerName);
}
二进制加载
LoadDataFromSlot 以原始二进制格式加载 SaveGame 数据,同步操作尽可用于此类加载。
LoadGameFromMemory 函数将二进制数据转换为 SaveGame 对象,函数为同步调用,成功时返回新的 USaveGame 对象,失败时返回空指针。
TArray<uint8> OuterSaveData;
if (UGameplayStatics::LoadDataFromSlot(OuterSaveData, TEXT("BinaryCPPSave"), 0))
{
if (UMySaveGame* BinarySaveGame = Cast<UMySaveGame>(UGameplayStatics::LoadGameFromMemory(OuterSaveData)))
{
UE_LOG(LogTemp, Warning, TEXT("BinaryLoad: %s"), *BinarySaveGame->PlayerName);
}
}

浙公网安备 33010602011771号