추가해야할 모듈
.h
UFUNCTION(BlueprintCallable, Category = "Game|SaveData|Editor")
static bool ExportSaveGameToJsonFile(const FString& SlotName, int32 UserIndex);
UFUNCTION(BlueprintCallable, Category = "Game|SaveData|Editor")
static bool ImportSaveGameFromJsonFile(const FString& SlotName, int32 UserIndex);
static bool ExportSaveGameToJson(USaveGame* Save, FString& OutJsonString);
static USaveGame* ImportSaveGameFromJson(const FString& JsonString);
#include "GameFramework/SaveGame.h"
#include "DesktopPlatformModule.h"
#include "JsonObjectConverter.h"
#include "Kismet/GameplayStatics.h"
#include "Logging/MessageLog.h"
#include "Misc/FileHelper.h"
#include "Widgets/SWindow.h"
#include "Dom/JsonObject.h"
#include "Framework/Application/SlateApplication.h"
#define LOCTEXT_NAMESPACE "ReseachBlueprintFunctionLibrary"
bool UReseachBlueprintFunctionLibrary::ExportSaveGameToJsonFile(const FString& SlotName, int32 UserIndex)
{
if (!UGameplayStatics::DoesSaveGameExist(SlotName, UserIndex))
{
FMessageLog("EditorErrors").Error(FText::Format(LOCTEXT("SaveGameDoesNotExit", "Save Game '{0}' does not exist, cannot export save game"), FText::FromString(SlotName)));
FMessageLog("EditorErrors").Notify(LOCTEXT("ExportFailNotification", "Failed to export save game"));
return false;
}
USaveGame* SaveGame = UGameplayStatics::LoadGameFromSlot(SlotName, UserIndex);
if (!SaveGame)
{
FMessageLog("EditorErrors").Error(FText::Format(LOCTEXT("SaveGameFailedToLoad", "Save Game '{0}' failed to load, cannot export save game"), FText::FromString(SlotName)));
FMessageLog("EditorErrors").Notify(LOCTEXT("ExportFailNotification", "Failed to export save game"));
return false;
}
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
if (!DesktopPlatform)
{
FMessageLog("EditorErrors").Error(LOCTEXT("ExportBadDesktopPlatform", "Unable to retrieve IDesktopPlatform, cannot export save game"));
FMessageLog("EditorErrors").Notify(LOCTEXT("ExportFailNotification", "Failed to export save game"));
return false;
}
TSharedPtr<SWindow> ParentWindow = FSlateApplication::Get().GetActiveTopLevelWindow();
void* ParentWindowHandle = (ParentWindow.IsValid() && ParentWindow->GetNativeWindow().IsValid())
? ParentWindow->GetNativeWindow()->GetOSWindowHandle()
: nullptr;
FString asd = SlotName;
TArray<FString> SelectedFiles;
bool Result = DesktopPlatform->SaveFileDialog(
ParentWindowHandle,
TEXT("Export Save Game"),
FPaths::ProjectDir(),
FString::Printf(TEXT("%s.json"), *asd),
TEXT("JSON Files|*.json"),
EFileDialogFlags::None,
SelectedFiles);
if (!Result || SelectedFiles.Num() == 0)
{
return false;
}
FString JsonString;
if (!ExportSaveGameToJson(SaveGame, JsonString))
{
FMessageLog("EditorErrors").Error(LOCTEXT("ExportSaveFailedJson", "Failed to export save, json error"));
FMessageLog("EditorErrors").Notify(LOCTEXT("ExportFailNotification", "Failed to export save game"));
}
if (!FFileHelper::SaveStringToFile(JsonString, *SelectedFiles[0]))
{
FMessageLog("EditorErrors").Error(FText::Format(LOCTEXT("ExportSaveFailed", "Failed to export save to '{0}'"), FText::FromString(SelectedFiles[0])));
FMessageLog("EditorErrors").Notify(LOCTEXT("ExportFailNotification", "Failed to export save game"));
return false;
}
return true;
}
bool UReseachBlueprintFunctionLibrary::ImportSaveGameFromJsonFile(const FString& SlotName, int32 UserIndex)
{
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
if (!DesktopPlatform)
{
FMessageLog("EditorErrors").Error(LOCTEXT("ImportBadDesktopPlatform", "Unable to retrieve IDesktopPlatform, cannot import save game"));
FMessageLog("EditorErrors").Notify(LOCTEXT("ImportFailNotification", "Failed to import save game"));
return false;
}
TSharedPtr<SWindow> ParentWindow = FSlateApplication::Get().GetActiveTopLevelWindow();
void* ParentWindowHandle = (ParentWindow.IsValid() && ParentWindow->GetNativeWindow().IsValid())
? ParentWindow->GetNativeWindow()->GetOSWindowHandle()
: nullptr;
TArray<FString> SelectedFiles;
bool Result = DesktopPlatform->OpenFileDialog(
ParentWindowHandle,
TEXT("Import Save Game"),
FPaths::ProjectDir(),
TEXT(""),
TEXT("JSON Files|*.json"),
EFileDialogFlags::None,
SelectedFiles);
if (!Result || SelectedFiles.Num() == 0)
{
return false;
}
FString JsonString;
if (!FFileHelper::LoadFileToString(JsonString, *SelectedFiles[0]))
{
FMessageLog("EditorErrors").Error(FText::Format(LOCTEXT("ImportFileFailed", "Failed to import save from '{0}'"), FText::FromString(SelectedFiles[0])));
FMessageLog("EditorErrors").Notify(LOCTEXT("ImportFailNotification", "Failed to import save game"));
return false;
}
USaveGame* SaveGame = ImportSaveGameFromJson(JsonString);
if (!SaveGame)
{
FMessageLog("EditorErrors").Error(FText::Format(LOCTEXT("ImportSaveFileFailed", "Failed to import save from '{0}', possible parse error"), FText::FromString(SelectedFiles[0])));
FMessageLog("EditorErrors").Notify(LOCTEXT("ImportFailNotification", "Failed to import save game"));
return false;
}
if (!UGameplayStatics::SaveGameToSlot(SaveGame, SlotName, UserIndex))
{
FMessageLog("EditorErrors").Error(FText::Format(LOCTEXT("UnableToSaveImport", "Failed to save imported save game to slot '{0}'"), FText::FromString(SlotName)));
FMessageLog("EditorErrors").Notify(LOCTEXT("ImportFailNotification", "Failed to import save game"));
return false;
}
return true;
}
bool UReseachBlueprintFunctionLibrary::ExportSaveGameToJson(USaveGame* Save, FString& OutJsonString)
{
if (!IsValid(Save))
{
return false;
}
FExportedSaveGame Export;
Export.SaveGame = Save;
return FJsonObjectConverter::UStructToJsonObjectString(Export, OutJsonString);
}
USaveGame* UReseachBlueprintFunctionLibrary::ImportSaveGameFromJson(const FString& JsonString)
{
FExportedSaveGame Import;
if (!FJsonObjectConverter::JsonObjectStringToUStruct(JsonString, &Import, 0, 0))
{
return nullptr;
}
return Import.SaveGame;
}
#undef LOCTEXT_NAMESPACE