Implementing Binary Serialization Using C#.
- .NET Core 2.1 and later versions.
- Unity 2021 and later versions.
- Use Code Generation to Avoid Reflection.
- Serialization with zero GC. (Depends on the data type being a value type and not containing any reference types)
- Simple and easy to use.
On Windows
cd Unity
Build.bat
./CopyDllTo.bat ${UNITY_PROJECT_DIR}\Assets\CompactBuffer
On MacOS and Linux
cd Unity
./Build.sh
./CopyDllTo.sh ${UNITY_PROJECT_DIR}/Assets/CompactBuffer- Serializers
- Protocols
[CompactBuffer.GenCode]
public class LiveData
{
public Guid guid;
public string UserName;
}
var serailizer = CompactBuffer.Serializers.GetSerializer<LiveData>();
var bytes = new byte[1000];
var writer = new BufferWriter(bytes);
var liveData = new LiveData();
serializer.Write(writer, ref liveData);
var reader = new BufferReader(bytes, 0, writer.Length);
liveData = null;
serializer.Read(reader, ref liveData);Define Protocol
[ProtocolId(0)]
public interface ISyncUserData : IProtocol
{
void Sync(string type, string data);
}Proxy Example
public class ProtocolSender : IProtocolSender
{
public BufferWriter GetStreamWriter()
{
var bytes = new byte[10000];
return BufferWrite(bytes);
}
public void Send(BufferWriter writer, byte channel)
{
// Send writer.GetWriteBytes()
}
}
var proxy = Protocol.GetProxy<ISyncUserData>(sender)
proxy.Sync("type", "data");Stub Example
public class SyncUserDataImpl : ISyncUserData
{
public void Sync(string type, string data)
{
// do something
}
}
var target = new SyncDataImpl();
var stub = Protocol.GetStub<ISyncUserData>(target);
stub.Dispach(bufferReader);- Overwrite
- Float16
- 7BitEncoded
- Channel
public struct Location
{
[CompactBuffer.Overwrite(typeof(Vector3Serializer))]
public System.Numerics.Vector3 Position;
}public struct Location
{
public System.Numerics.Vector3 Position;
}
[CompactBuffer.Overwrite(typeof(System.Numerics.Vector3))]
public class Vector3Serializer : CompactBuffer.ICompactBufferSerializer
{
public static void Read(CompactBuffer.BufferReader reader, ref System.Numerics.Vector3 target)
{
target.X = reader.ReadSingle();
target.Y = reader.ReadSingle();
target.Z = reader.ReadSingle();
}
public static void Write(CompactBuffer.BufferWriter writer, in System.Numerics.Vector3 target)
{
writer.Write(target.X);
writer.Write(target.Y);
writer.Write(target.Z);
}
public static void Copy(in System.Numerics.Vector3 src, ref System.Numerics.Vector3 dst)
{
dst.X = src.X;
dst.Y = src.Y;
dst.Z = src.Z;
}
}[Float16(1000)]
public struct Position
{
public float x, y, z;
}
public struct Movement
{
[Float16(1)]
float NormalX;
[Float16(1)]
float NormalY;
[Float16(1)]
float NormalZ;
}
[ProtocolId(0)]
public interface ISyncPosition : IProtocol
{
void Sync(
[Float16(1)] float normalX,
[Float16(1)] float normalY,
[Float16(1)] float normalZ,
);
}The original float takes up 4 bytes, but after adding float16attribute, it only takes up 2 bytes.
public struct Data
{
[SevenBitEncoded]
public int Count;
}
[ProtocolId(0)]
public interface ISyncPosition : IProtocol
{
void Sync(
[SevenBitEncoded] int Count
);
}public enum ChannelType : byte
{
OrderAndReliable,
OrderAndUnreliable,
DisorderAndUnreliable,
}
[ProtocolId(0)]
public interface ISyncPosition : IProtocol
{
[Channel(ChannelType.OrderAndReliable)]
void Sync(Vector3 position);
[Channel(ChannelType.OrderAndUnreliable)]
void LastPosition(Vector3 position)
[Channel(ChannelType.DisorderAndUnreliable)]
void Chat(string message);
}- Add CompactBufferGroup
- Add asmdef
- Click the menu [Tools/CompactBuffer/Generate] in the Unity editor.
- CodeGen.CompactBuffer.cs and CodeGen.Protocol.cs have been generated in the directory of the asmdef file.
If code generation results in a compilation error, please click on Unity Editor menu's [Tools/CompactBuffer/Clean] then regenerate the code.
CompactBuffer is licensed under the MIT license.