I have to admit that I’m finding this section a little confusing. Below was my challenge solution to serialize myself. My changes are worth noting and I have some questions listed below.
bool FAuraGameplayEffectContext::NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess)
{
// Serialize the base class
Super::NetSerialize(Ar, Map, bOutSuccess);
enum RepFlag
{
REP_IsBlockedHit,
REP_IsCriticalHit,
REP_MAX
};
uint8 RepBits = 0;
if (Ar.IsSaving())
{
if (bIsBlockedHit)
{
RepBits |= 1 << REP_IsBlockedHit;
}
if (bIsCriticalHit)
{
RepBits |= 1 << REP_IsCriticalHit;
}
}
Ar.SerializeBits(&RepBits, REP_MAX);
if (Ar.IsLoading())
{
bIsBlockedHit = RepBits & (1 << REP_IsBlockedHit);
bIsCriticalHit = RepBits & (1 << REP_IsCriticalHit);
}
bOutSuccess = true;
return true;
}
Note that I call the base class rather than duplicate that code, and handle loading differently. I prefer not to duplicate base code if I can avoid it so this seems better. The same number of bytes serialized either way as we now have 9 bits to serialize. Any reason not to do this?
Also looking at Stephen’s code I see him both save/loading the packed bits like I do, and later serializing the Booleans again as follows:
if (RepBits & (1 << 7))
{
Ar << bIsBlockedHit;
}
if (RepBits & (1 << 8))
{
Ar << bIsCriticalHit;
}
Isn’t this just serializing the crit and blocked bools again for both load and save if the bit is set? Unnecessarily bloating the net serialize structure by two bools? See the load technique I used instead.