Thanks for the advice Josh! That does seems like a more compact way of doing it. I’m just having trouble reading back the data now (also having the same issues when using the other method)
So, this is what the SaveGame function looks like right now.
static bool SaveGame3(const FString& FileName)
{
// Create a writer and hold it in this FString
FString JsonStr;
TSharedRef > JsonWriter = TJsonWriterFactory<>::Create(&JsonStr);
JsonWriter->WriteObjectStart();
// ObjectInstance1 (will be MyObject->GetFullPath() or something)
JsonWriter->WriteObjectStart("ObjectInstance1");
JsonWriter->WriteValue("SomeBool", true);
JsonWriter->WriteValue("SomeString", *FileName);
JsonWriter->WriteValue("SomeNumber", 32.0);
JsonWriter->WriteObjectEnd();
// ObjectInstance2
JsonWriter->WriteObjectStart("ObjectInstance2");
JsonWriter->WriteValue("SomeBool", false);
JsonWriter->WriteValue("SomeString", TEXT("Bleh"));
JsonWriter->WriteValue("SomeNumber", 64.0);
JsonWriter->WriteObjectEnd();
JsonWriter->WriteObjectEnd();
// Close the writer and finalize the output such that JsonStr has what we want
JsonWriter->Close();
FString FullPath = FPaths::GameSavedDir();
FullPath += FileName;
FArchive* SaveFile = GFileManager->CreateFileWriter(*FullPath);
if (!SaveFile)
{
return false;
}
*SaveFile << JsonStr;
// this will commit the save to disk and free up your memory :)
delete SaveFile;
return true;
}
The idea is to save two (or more) instances of a same class and the values back.
Now, to the data back, I tried two methods:
static void LoadGame(const FString& FileName)
{
FString FullPath = FPaths::GameSavedDir();
FullPath += FileName;
FArchive* SaveFile = GFileManager->CreateFileReader(*FullPath);
if (!SaveFile)
{
return;
}
TSharedRef > JsonReader = TJsonReaderFactory<>::Create(SaveFile);
EJsonNotation::Type ValueType;
while (JsonReader->ReadNext(ValueType))
{
if (ValueType == EJsonNotation::Boolean)
{
bool b = JsonReader->GetValueAsBoolean();
}
else if (ValueType == EJsonNotation::String)
{
FString b = JsonReader->GetValueAsString();
}
}
delete SaveFile;
}
and
static void LoadGame2(const FString& FileName)
{
FString FullPath = FPaths::GameSavedDir();
FullPath += FileName;
FArchive* SaveFile = GFileManager->CreateFileReader(*FullPath);
if (!SaveFile)
{
return;
}
TSharedPtr JsonObject;
TSharedRef > JsonReader = TJsonReaderFactory<>::Create(SaveFile);
if (FJsonSerializer::Deserialize(JsonReader,JsonObject) &&
JsonObject.IsValid())
{
TSharedPtr Object1 = JsonObject->GetObjectField(TEXT("ObjectInstance1"));
TSharedPtr Object2 = JsonObject->GetObjectField(TEXT("ObjectInstance2"));
FString a = JsonObject->GetStringField(TEXT("SomeString"));
bool b = JsonObject->GetBoolField(TEXT("SomeBool2"));
}
}
But both of them fail. The JSonReader
has the following in its ErrorMessage
property:
ErrorMessage = L"Invalid Json Token. Line: 1 Ch: 1"
What am I doing wrong?
By the way, this is what the saved file looks like:
Ï {
"ObjectInstance1":
{
"SomeBool": true,
"SomeString": "Quicksave.save",
"SomeNumber": 32
},
"ObjectInstance2":
{
"SomeBool": false,
"SomeString": "Bleh",
"SomeNumber": 64
}
}
I tried manually deleting that Ï
from the beginning, but didn’t help too.