NetworkComponent
DOTSNET can automatically sync components for you.
For example, let's say we need a Health component with:
Current health: this changes when attacked / when recovering.
Max health: this never changes.
We can define a Health : NetworkComponent
, which DOTSNET will automatically:
Include in Spawn messages
Synchronize every
NetworkServer.snapshotInterval
seconds
NetworkComponent Interface
First, we need to create a Health struct that implements the NetworkComponent
interface:
public struct Health : NetworkComponent
{
public int current;
public int max;
// server authoritative
public SyncDirection GetSyncDirection() =>
SyncDirection.SERVER_TO_CLIENT;
// only sync current. max is always the same.
public bool Serialize(ref NetworkWriter128 writer) =>
writer.WriteInt(current);
// only sync current. max is always the same.
public bool Deserialize(ref NetworkReader128 reader) =>
reader.ReadInt(out current);
}
// need to define a serializer for every NetworkComponent
public class HealthSerializer : NetworkComponentSerializer<Health> {}
Important: we also need to define a NetworkComponentSerializer<T>
for every NetworkComponent
.
NetworkComponent
implements IComponentData
automatically and is burstable.
In the above example, DOTSNET will automatically serialize current
health and include it in Snapshots, from client to server. If the client tries to modify it, it will have no effect unless we change sync direction to CLIENT_TO_SERVER
which would make it client authoritative.
NetworkComponentSerializer<T> Fast
The one-liner NetworkComponentSerializer<T>
uses an EntityQuery<T>
internally because a generic Entites.ForEach<T>
is not supported by ECS.
If necessary, feel free to overwrite the Serializer's SerializeAll
/ DeserializeAll
functions for maximum performance. It's more verbose though:
public class HealthSerializer : NetworkComponentSerializer<Health>
{
public override void SerializeAll(CurrentWorld currentWorld)
{
ushort key = Key; // copy for Burst
Entities.ForEach((ref NetworkComponentsSerialization serialization, in NetworkIdentity identity, in Health component) =>
{
Serialize(currentWorld, key, identity, component, ref serialization);
})
.Run();
}
public override void DeserializeAll(CurrentWorld currentWorld)
{
ushort key = Key; // copy for Burst
Entities.ForEach((ref NetworkComponentsDeserialization deserialization, ref Health component, in NetworkIdentity identity) =>
{
Deserialize(currentWorld, key, identity, ref component, ref deserialization);
})
.Run();
}
}
For your own components, simply copy the above code and replace Health
with your components type. Put that code right below where you define your component, in the same file. Don't worry about what it does. it just needs to be defined.
Last updated