Введение
Допустим, вы создали свою USTRUCT в C++ и хотите её сериализовать.
USTRUCT(BlueprintType)
struct FComplexStruct
{
	GENERATED_BODY()
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FNonSerializableStruct FirstStruct;
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FSerializableStruct SecondStruct;
};
Обычно, достаточно просто пометить нужные поля как SaveGame.
USTRUCT(BlueprintType)
struct FComplexStruct
{
    GENERATED_BODY()
    // Не поддерживает сериализацию
    UPROPERTY(EditAnywhere, BlueprintReadWrite, SaveGame)
    FNonSerializableStruct FirstStruct;
    // Поддерживает сериализацию
    UPROPERTY(EditAnywhere, BlueprintReadWrite, SaveGame)
    FSerializableStruct SecondStruct;
};
Но вот проблема, для этого они сами должны поддерживать сериализацию. К сожалению, одна из наших переменных ее не поддерживает. В моем случае, это структура FNonSerializableStruct. Из-за этого сериализуется только вторая структура, хоть мы и пометили SaveGame обе.
Решение
И как же тогда быть? В таком случае, нам придется вручную сериализовать нашу структуру. Благо, это довольно просто сделать. Для этого нам нужно за пределами структуры, глобально, для файла, добавить следующее:
inline FArchive& operator<<(FArchive& Ar, FComplexStruct& Save)
{
	Save.Serialize(Ar);
	return Ar;
}
template <>
struct TStructOpsTypeTraits<FComplexStruct> : public TStructOpsTypeTraitsBase2<FComplexStruct>
{
	enum
	{
		WithSerializer = true
	};
};
Тут, в шаблонной структуре, мы говорим движку, что мы хотим вручную сериализовать нашу структуру.
Перегрузка оператора << добавлена чисто для удобства, дабы не вызывать всегда метод Serialize руками, если мы захотим использовать нашу структуру как поле другой структуры/класса.
Окей, что делать дальше? Мы ведь так и не написали нашу сериализацию.
Я уже упомянул выше метод Serialize. Его нам и надо добавить в нашу структуру. Движок его вызовет сам, когда надо. Сделает он это благодаря коду, который мы написали выше.
bool Serialize(FArchive& Ar)
{
	// Сериализуем частями, т.к. поддержки нет
    Ar << FirstStruct.Type;
    Ar << FirstStruct.Class;
    Ar << FirstStruct.Object;
    // Сериализуем целиком, т.к. есть поддержка
    Ar << SecondStruct;
	return true;
}
Полный код
USTRUCT(BlueprintType)
struct FComplexStruct
{
    GENERATED_BODY()
    // Не поддерживает сериализацию
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    FNonSerializableStruct FirstStruct;
    // Поддерживает сериализацию
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    FSerializableStruct SecondStruct;
    bool Serialize(FArchive& Ar)
    {
        // Сериализуем частями, т.к. поддержки нет
        Ar << FirstStruct.Type;
    	Ar << FirstStruct.Class;
    	Ar << FirstStruct.Object;
        // Сериализуем целиком, т.к. есть поддержка
    	Ar << SecondStruct;
  
    	return true;
    }
};
inline FArchive& operator<<(FArchive& Ar, FComplexStruct& Save)
{
	Save.Serialize(Ar);
	return Ar;
}
template <>
struct TStructOpsTypeTraits<FComplexStruct> : public TStructOpsTypeTraitsBase2<FComplexStruct>
{
	enum
	{
		WithSerializer = true
	};
};
Улучшение
Можно заметить, что код добавления поддержки сериализации довольно шаблонный. Что это означает? Мы можем сделать макрос, дабы сильно облегчить добавление поддержки для других структур!
#define MAKE_SERIALIZABLE_STRUCT(Name) \
	inline FArchive& operator<<(FArchive& Ar, Name& Save) \
	{ \
		Save.Serialize(Ar); \
		return Ar; \
	} \
	template<> \
	struct TStructOpsTypeTraits<Name> : public TStructOpsTypeTraitsBase2<Name> \
	{ \
		enum  \
		{ \
			WithSerializer = true, \
		}; \
	};
Теперь мы можем просто закинуть наш макрос в какой-нибудь хедер и довольно лаконично добавить поддержку сериализации для любой нашей структуры.
Финальный код
USTRUCT(BlueprintType)
struct FComplexStruct
{
    GENERATED_BODY()
    // Не поддерживает сериализацию
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    FNonSerializableStruct FirstStruct;
    // Поддерживает сериализацию
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    FSerializableStruct SecondStruct;
    bool Serialize(FArchive& Ar)
    {
        // Сериализуем частями, т.к. поддержки нет
        Ar << FirstStruct.Type;
    	Ar << FirstStruct.Class;
    	Ar << FirstStruct.Object;
        // Сериализуем целиком, т.к. есть поддержка
    	Ar << SecondStruct;
  
    	return true;
    }
};
MAKE_SERIALIZABLE_STRUCT(FComplexStruct);
Итог
Теперь вы можете без труда добавлять поддержку сериализации для собственных структур в Unreal Engine, даже если их поля изначально не поддерживают эту функцию.