Arrays and native containers
Arrays of C# primitive types, like int[]
, and Unity primitive types, such as Vector3
, are serialized by built-in serialization code. Otherwise, any array of types that aren't handled by the built-in serialization code, such as string[]
, needs to be handled through a container class or structure that implements the INetworkSerializable
interface.
Built-In Primitive Types Example
Using built-in primitive types is fairly straight forward:
[Rpc(SendTo.Server)]
void HelloServerRpc(int[] scores, Color[] colors) { /* ... */ }
INetworkSerializable Implementation Example
There are many ways to handle sending an array of managed types.
The below example is a simple string
container class that implements INetworkSerializable
and can be used as an array of "StringContainers":
[Rpc(SendTo.ClientsAndHost)]
void SendMessagesClientRpc(StringContainer[] messages)
{
foreach (var stringContainer in stringContainers)
{
Debug.Log($"{stringContainer.SomeText}");
}
}
public class StringContainer : INetworkSerializable
{
public string SomeText;
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{
if (serializer.IsWriter)
{
serializer.GetFastBufferWriter().WriteValueSafe(SomeText);
}
else
{
serializer.GetFastBufferReader().ReadValueSafe(out SomeText);
}
}
}
Native Containers
Netcode for GameObjects supports NativeArray
and NativeList
native containers with built-in serialization, RPCs, and NetworkVariables. However, you cannot nest either of these containers without causing a crash.
A few examples of nesting that will cause a crash:
NativeArray<NativeList<T>>
NativeList<NativeArray<T>>
NativeArray<NativeArray<T>>
NativeList<NativeList<T>>
NativeArray<T>
To serialize a NativeArray
container, use serializer.SerializeValue(ref Array)
.
NativeList<T>
To serialize a NativeList
container, you must:
- Ensure your assemblies reference
Collections
. - You must add
UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
to your Scriptiong Define Symbols list.- From the Unity Editor top bar menu, go to Edit > Project Settings... > Player.
- Select the Other Settings dropdown.
- Scroll to Script Compilation > Scripting Define Symbols.
- Add
UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
.
- Use
serializer.SerializeValue(ref List)
as your serialization syntax.
When using NativeLists
within INetworkSerializable
, the list ref
value must be a valid, initialized NativeList
.
NetworkVariables are similar that the value must be initialized before it can receive updates.
For example,
public NetworkVariable<NativeList<byte>> ByteListVar = new NetworkVariable<NativeList<byte>>{Value = new NativeList<byte>(Allocator.Persistent)};
RPCs do this automatically.