Float Pack
A float value can be compressed using FloatPackAttribute
The float value will be quantized and turned into an integer with at least the resolution that is given in the attribute.
The real resolution used is calculated from the bitcount
required to pack the value. For example, if the max is 100
, and the resolution is 0.1f
, then there are 2000
discrete values are needed to pack this. This requires 11 bits. 11 bits allow for 2047
discrete values so the real resolution used will be 0.0977f
.
Values are packed so that 0 will unpack are 0, and other values are rounded to the nearest int so that rounding errors stay as low as possible.
Values are clamped so values out of range will be packed as min/max values instead
Use cases
- A Value with a maximum value
Supported Types
- Float
Example 1
Health which is between 0 and 100
public class MyNetworkBehaviour : NetworkBehaviour
{
[SyncVar, FloatPack(100f, 0.02f)]
public int Health;
}
Max = 100
, resolution = 0.02f
so bit count is 14
health = 57.2f
will serialize to 01_0010_0100_1101
and deserialize to 57.197f
health = -13.5f
will serialize to 11_1011_1010_1110
and deserialize to -13.503f
health = 120f
will be clamped to 100f
Example 2
A Percent that where you only want to send 8 bits
public class MyNetworkBehaviour : NetworkBehaviour
{
[SyncVar, FloatPack(1f, 8)]
public int Percent;
}
Max = 1f
, bitCount = 8
so resolution will be 0.00787f
Generated Code
Source:
[SyncVar, FloatPack(100f, 0.02f)]
public int myValue;
Generated:
private FloatPacker myValue__Packer = new FloatPacker(100f, 0.02f);
public override bool SerializeSyncVars(NetworkWriter writer, bool initialState)
{
ulong syncVarDirtyBits = base.SyncVarDirtyBits;
bool result = base.SerializeSyncVars(writer, initialize);
if (initialState)
{
myValue__Packer.Pack(writer, this.myValue);
return true;
}
writer.Write(syncVarDirtyBits, 1);
if ((syncVarDirtyBits & 1UL) != 0UL)
{
myValue__Packer.Pack(writer, this.myValue);
result = true;
}
return result;
}
public override void DeserializeSyncVars(NetworkReader reader, bool initialState)
{
base.DeserializeSyncVars(reader, initialState);
if (initialState)
{
this.myValue = myValue__Packer.Unpack(reader);
return;
}
ulong dirtyMask = reader.Read(1);
if ((dirtyMask & 1UL) != 0UL)
{
this.myValue = myValue__Packer.Unpack(reader);
}
}
last updated for Mirage v101.8.0