Serialization is the process of converting an object or data structure into a format that can be easily stored or transmitted, and subsequently reconstructed. In Unreal Engine, serialization is often used for:
Unreal Engine uses several classes and methods for serialization, built around Unreal's reflection system. The core class for serialization is FArchive
, which provides the basic interface for reading and writing data.
FArchive
: The base class for serialization, providing fundamental methods like <<
(for serializing individual properties) and Serialize
.FMemoryWriter / FMemoryReader
: Derived from FArchive
, these classes are used to serialize to and from memory buffers.FObjectAndNameAsStringProxyArchive
: A specialized archive for serializing UObjects with reference tracking.FBufferArchive
: A simple implementation of FArchive
that writes to an array of bytes, useful for custom serialization.Let’s start with a simple example of serializing a custom struct to a binary format.
// Define a simple struct
USTRUCT(BlueprintType)
struct FMyStruct
{
GENERATED_BODY()
UPROPERTY()
int32 MyInt;
UPROPERTY()
float MyFloat;
UPROPERTY()
FString MyString;
// Implement custom serialization
friend FArchive& operator<<(FArchive& Ar, FMyStruct& MyStruct)
{
Ar << MyStruct.MyInt;
Ar << MyStruct.MyFloat;
Ar << MyStruct.MyString;
return Ar;
}
};
// Serializing the struct to a file
void SaveStructToFile(const FString& FilePath, const FMyStruct& Data)
{
// Create a binary archive writer
FBufferArchive Archive;
Archive << const_cast<FMyStruct>(Data);
// Write to disk
if (FFileHelper::SaveArrayToFile(Archive, *FilePath))
{
UE_LOG(LogTemp, Log, TEXT("Saved successfully!"));
}
Archive.FlushCache();
Archive.Empty();
}
// Deserializing the struct from a file
bool LoadStructFromFile(const FString& FilePath, FMyStruct& Data)
{
TArray<uint8> BinaryArray;
if (FFileHelper::LoadFileToArray(BinaryArray, *FilePath))
{
FMemoryReader FromBinary = FMemoryReader(BinaryArray, true); // true: Free binary array after read
FromBinary.Seek(0);
FromBinary << Data;
FromBinary.FlushCache();
BinaryArray.Empty();
return true;
}
return false;
}
For UObjects, Unreal’s Serialize
function is used. This method is automatically called for UObjects when you serialize them using an archive. You can override this function in your custom classes to handle specific serialization logic.
class UMyObject : public UObject
{
GENERATED_BODY()
public:
UPROPERTY()
int32 MyInt;
UPROPERTY()
FString MyString;
virtual void Serialize(FArchive& Ar) override
{
Super::Serialize(Ar);
Ar << MyInt;
Ar << MyString;
}
};
If you need to serialize to a custom format (e.g., XML, JSON, or a proprietary binary format), you’ll use a combination of FArchive
or FStructuredArchive
, custom parsers, and serialization functions.
Example: JSON Serialization
// JSON Serialization Example
void SerializeToJson(const FString& FilePath, const FMyStruct& Data)
{
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
JsonObject->SetNumberField(TEXT("MyInt"), Data.MyInt);
JsonObject->SetNumberField(TEXT("MyFloat"), Data.MyFloat);
JsonObject->SetStringField(TEXT("MyString"), Data.MyString);
FString OutputString;
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&OutputString);
FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer);
FFileHelper::SaveStringToFile(OutputString, *FilePath);
}
bool DeserializeFromJson(const FString& FilePath, FMyStruct& Data)
{
FString JsonString;
if (FFileHelper::LoadFileToString(JsonString, *FilePath))
{
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(JsonString);
TSharedPtr<FJsonObject> JsonObject;
if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
{
Data.MyInt = JsonObject->GetIntegerField(TEXT("MyInt"));
Data.MyFloat = JsonObject->GetNumberField(TEXT("MyFloat"));
Data.MyString = JsonObject->GetStringField(TEXT("MyString"));
return true;
}
}
return false;
}
UCLASS
, USTRUCT
, etc.) as it simplifies serialization and ensures compatibility with UE features like garbage collection and network replication.FArchive
.Serialization in Unreal Engine is a powerful tool that allows developers to save and restore game states, transmit data over the network, and more. By leveraging Unreal's serialization system and following best practices, you can create efficient and maintainable systems for managing your game's data. Always keep in mind the specific needs of your project when choosing the serialization approach, whether it's binary, JSON, or a custom format.