Skip to content

Commit 815c063

Browse files
EmandMjabbacakes
andauthored
Apply suggestions from code review
Co-authored-by: Amy Reeve <amy.reeve@unity3d.com>
1 parent 8696eed commit 815c063

12 files changed

Lines changed: 44 additions & 34 deletions

com.unity.netcode.gameobjects/Documentation~/TableOfContents.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@
7575
* [Unity primitives](advanced-topics/serialization/unity-primitives.md)
7676
* [Enum types](advanced-topics/serialization/enum-types.md)
7777
* [Arrays](advanced-topics/serialization/serialization-arrays.md)
78-
* [INetworkSerializable](advanced-topics/serialization/inetworkserializable.md)
79-
* [INetworkSerializeByMemcpy](advanced-topics/serialization/inetworkserializebymemcpy.md)
80-
* [NetworkObject serialization](advanced-topics/serialization/networkobject-serialization.md)
78+
* [Customize serializable types with INetworkSerializable](advanced-topics/serialization/inetworkserializable.md)
79+
* [Serialize unmanaged structs with INetworkSerializeByMemcpy](advanced-topics/serialization/inetworkserializebymemcpy.md)
80+
* [NetworkObject and NetworkBehaviour serialization](advanced-topics/serialization/networkobject-serialization.md)
8181
* [FastBufferWriter and FastBufferReader](advanced-topics/fastbufferwriter-fastbufferreader.md)
8282
* [BufferSerializer](advanced-topics/bufferserializer.md)
8383
* [Custom serialization](advanced-topics/custom-serialization.md)

com.unity.netcode.gameobjects/Documentation~/advanced-topics/bufferserializer.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# BufferSerializer
22

3-
It's recommended to read the [serialization overview](./serialization/serialization-overview.md) before reading this documentation.
3+
> [!NOTE]
4+
> Read the [Serialization overview](./serialization/serialization-overview.md) page to understand the basics of serialization before learning how to use `BufferSerializer`.
45
56
`BufferSerializer<TReaderWriter>` is the bi-directional serializer primarily used for serializing within [`INetworkSerializable`](serialization/inetworkserializable.md) types. It wraps [`FastBufferWriter` and `FastBufferReader`](fastbufferwriter-fastbufferreader.md) to provide high performance serialization, but has a couple of differences to make it more user-friendly:
67

com.unity.netcode.gameobjects/Documentation~/advanced-topics/custom-serialization.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,42 @@
11
# Custom serialization
22

3-
Before reading these docs, ensure you have read the [serialization overview](./serialization/serialization-overview.md)
3+
> [!NOTE]
4+
> Read the [Serialization overview](./serialization/serialization-overview.md) page to understand the basics of serialization before learning how to customize serialization.
45
56
Netcode for GameObjects provide support for serializing any unsupported types, and with the API provided, it can even be done with types that you haven't defined yourself, those who are behind a 3rd party wall, such as .NET types. However, the way custom serialization is implemented for RPCs and NetworkVariables is slightly different.
67

7-
Let's explore different ways to implement custom serialization for a custom health struct.
8+
Netcode for GameObjects supports custom serialization of unsupported types, including those you haven't defined yourself, such as third-party .NET types. You can also use custom serialization to override how an existing supported type is serialized.
9+
10+
Custom serialization is implemented slightly differently for RPCs and NetworkVariables. The examples on this page provide different ways to serialization a custom health struct.
811

912
[!code-cs[](../../Tests/Editor/DocumentationCodeSamples/Serialization/SerializationCustomization.cs#HealthStruct)]
1013

1114
## FastBufferReader and FastBufferWriter
1215

13-
[`FastBufferReader` and `FastBufferWriter`](./fastbufferwriter-fastbufferreader.md) are the main serialization tools in Netcode for GameObjects. To register serialization for a custom type, or override an already handled type, you need to create extension methods for `FastBufferReader.ReadValueSafe()` and `FastBufferWriter.WriteValueSafe()`. Because the `FastBufferReader` and `FastBufferWriter` already know how to read and write primitive types you want to use this functionality to serialize your custom type.
16+
[`FastBufferReader` and `FastBufferWriter`](./fastbufferwriter-fastbufferreader.md) are the main serialization tools in Netcode for GameObjects. To register serialization for a custom type, or override an already handled type, you need to create extension methods for `FastBufferReader.ReadValueSafe()` and `FastBufferWriter.WriteValueSafe()`. `FastBufferReader` and `FastBufferWriter` can read and write primitive types, and you can extend this functionality to serialize your custom type.
1417

1518
[!code-cs[](../../Tests/Editor/DocumentationCodeSamples/Serialization/SerializationCustomization.cs#FastBuffer)]
1619

17-
Additionally, you may also need to add extensions for `FastBufferReader.ReadValue()`, `FastBufferWriter.WriteValue()` if you would like to provide for serialization without [bounds checking](./fastbufferwriter-fastbufferreader.md#bounds-checking)
20+
You may also need to add extensions for `FastBufferReader.ReadValue()`, `FastBufferWriter.WriteValue()` if you want to serialize without [bounds checking](./fastbufferwriter-fastbufferreader.md#bounds-checking)
1821

1922
## BufferSerializer
2023

21-
You can also add custom serialization support to the bi-directional [`BufferSerializer`](./bufferserializer.md). This will make this type readily available within [`INetworkSerializable`](serialization/inetworkserializable.md) types and in the [`NetworkBehaviour.OnSynchronize()` method](../components/core/networkbehaviour-synchronize.md#prespawn-synchronization-with-onsynchronize):
24+
You can also add custom serialization support to the bi-directional [`BufferSerializer`](./bufferserializer.md). This makes your custom type readily available within [`INetworkSerializable`](serialization/inetworkserializable.md) types and in the [`NetworkBehaviour.OnSynchronize()` method](../components/core/networkbehaviour-synchronize.md#prespawn-synchronization-with-onsynchronize):
2225

2326
[!code-cs[](../../Tests/Editor/DocumentationCodeSamples/Serialization/SerializationCustomization.cs#BufferSerializer)]
2427

25-
## Remote Procedure Call (RPC)
28+
## Remote procedure call (RPCs)
2629

2730
> [!NOTE]
28-
> Remote Procedure Calls (RPCs) can also use the Network Variable flow, but NetworkVariables can't use the RPC flow. The RPC flow is more efficient when only RPCs need to serialize the type. When a type is used by both NetworkVariables and RPCs you can implement just the NetworkVariable flow to lower maintenance requirements. Unity will select the RPC flow for RPCs if you have implemented both flows.
31+
> RPCs can use the Network Variable flow, but NetworkVariables can't use the RPC flow. The RPC flow is more efficient when only RPCs need to serialize the type. When a type is used by both NetworkVariables and RPCs, you can implement just the NetworkVariable flow to lower maintenance requirements. Unity will select the RPC flow for RPCs if you have implemented both flows.
2932
3033
To serialize a custom type, or override an already handled type, you need to create extension methods for `FastBufferReader.ReadValueSafe()` and `FastBufferWriter.WriteValueSafe()` as [outlined above](#fastbufferreader-and-fastbufferwriter).
3134

3235
The code generation for RPCs will automatically pick up and use these functions, as they'll become available via `FastBufferWriter` and `FastBufferReader` directly.
3336

3437
## NetworkVariable
3538

36-
Implementing [`INetworkSerializable`](./serialization/inetworkserializable.md) is the cleanest and most straightforward way to customize the serialization on a type within a [`NetworkVariable`](../basics/networkvariable.md). `UserNetworkVariableSerialization` provides runtime configuration to further override serialization of a type.
39+
Implementing [`INetworkSerializable`](./serialization/inetworkserializable.md) is the cleanest and most straightforward way to customize the serialization of a type within a [`NetworkVariable`](../basics/networkvariable.md). `UserNetworkVariableSerialization` provides runtime configuration to further override serialization of a type.
3740

3841
First you will need to create extension methods for `FastBufferReader.ReadValueSafe()` and `FastBufferWriter.WriteValueSafe()` as [outlined above](#fastbufferreader-and-fastbufferwriter).
3942

@@ -45,7 +48,7 @@ UserNetworkVariableSerialization<Health>.ReadValue = SerializationExtensions.Rea
4548
UserNetworkVariableSerialization<Health>.DuplicateValue = (in Health value, ref Health duplicatedValue) => duplicatedValue = value;
4649
```
4750

48-
`DuplicateValue` should return a complete deep copy of the value that `NetworkVariable<T>` compares to a previous value. It is used to check whether the value has changed. `DuplicateValue` avoids re-serializing it over the network every frame when it hasn't changed.
51+
`DuplicateValue` should return a complete deep copy of the value that `NetworkVariable<T>` compares to a previous value, which is used to check whether the value has changed. `DuplicateValue` avoids re-serializing it over the network every frame when it hasn't changed.
4952

5053
> [!NOTE]
5154
> `WriteValue`, `ReadValue` and `DuplicateValue` all need to be defined to customize your serialization.
@@ -55,7 +58,7 @@ UserNetworkVariableSerialization<Health>.DuplicateValue = (in Health value, ref
5558
5659
### Serializing delta updates
5760

58-
Simply reading and writing a value will provide the minimal amount of `NetworkVariable` functionality. This will synchronize your whole type any time any value within the type value changes. To provide sending delta updates rather than a full updates whenever your type has changed, implement the following functions:
61+
Reading and writing a value provides the minimal amount of `NetworkVariable` functionality. This will synchronize your whole type whenever any value within the type value changes. To support sending delta updates rather than a full update whenever your type has changed, implement the following functions:
5962

6063
- `WriteDelta`
6164
- `ReadDelta`

com.unity.netcode.gameobjects/Documentation~/advanced-topics/fastbufferwriter-fastbufferreader.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# FastBufferWriter and FastBufferReader
22

3-
It's recommended to read the [serialization overview](./serialization/serialization-overview.md) before reading this documentation.
3+
> [!NOTE]
4+
> Read the [Serialization overview](./serialization/serialization-overview.md) page to understand the basics of serialization before learning about `FastBufferWriter` and `FastBufferReader`.
45
56
The serialization and deserialization is done via `FastBufferWriter` and `FastBufferReader`. These have methods for serializing individual types and methods for serializing packed numbers, but in particular provide a high-performance method called `WriteValue()/ReadValue()` (for Writers and Readers, respectively) that can extremely quickly write an entire unmanaged struct to a buffer.
67

com.unity.netcode.gameobjects/Documentation~/advanced-topics/serialization/inetworkserializable.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
# INetworkSerializable
1+
# Customize serializable types with INetworkSerializable
22

3-
It's recommended to read the [serialization overview](./serialization/serialization-overview.md) to better understand this documentation.
3+
> [!NOTE]
4+
> Read the [Serialization overview](./serialization/serialization-overview.md) page to understand the basics of serialization before customizing serializable types with `INetworkSerializable`.
45
5-
You can use the `INetworkSerializable` interface to define custom serializable types. This interface has one function: `NetworkSerialize<T>(BufferSerializer<T> serializer)`. This function is provided a bi-directional [`BufferSerializer`](../bufferserializer.md) that you can use to implement bi-directional custom serialization.
6+
You can use the `INetworkSerializable` interface to define custom serializable types. This interface has one function: `NetworkSerialize<T>(BufferSerializer<T> serializer)`, which ingests a bi-directional [`BufferSerializer`](../bufferserializer.md) that you can use to implement bi-directional custom serialization.
67

7-
`INetworkSerializable` can be implemented on both unmanaged types *and* managed types. However, we recommend avoiding serializing managed types where possible to improve your game's performance.
8+
`INetworkSerializable` can be implemented on both managed and unmanaged types, although serializing managed types isn't recommended because it can reduce your game's performance.
89

910
```csharp
1011
struct SpawnPoint : INetworkSerializable

com.unity.netcode.gameobjects/Documentation~/advanced-topics/serialization/inetworkserializebymemcpy.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
# INetworkSerializeByMemcpy
1+
# Serialize unmanaged structs with INetworkSerializeByMemcpy
22

3-
It's recommended to read the [serialization overview](./serialization/serialization-overview.md) to better understand this documentation.
3+
> [!NOTE]
4+
> Read the [Serialization overview](./serialization/serialization-overview.md) page to understand the basics of serialization before using `INetworkSerializeByMemcpy` to serialize unmanaged structs.
45
56
The `INetworkSerializeByMemcpy` interface is used to mark an unmanaged struct type as being trivially serializable over the network by directly copying the whole struct, byte-for-byte, as it appears in memory, into and out of the buffer. This can offer some benefits for performance compared to serializing one field at a time, especially if the struct has many fields in it, but it may be less efficient from a bandwidth-usage perspective, as fields will often be padded for memory alignment and you won't be able to "pack" any of the fields to optimize for space usage.
67

com.unity.netcode.gameobjects/Documentation~/advanced-topics/serialization/networkobject-serialization.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
# NetworkObject and NetworkBehaviour
1+
# NetworkObject and NetworkBehaviour serialization
22

3-
It's recommended to read the [serialization overview](./serialization/serialization-overview.md) to better understand this documentation.
3+
> [!NOTE]
4+
> Read the [Serialization overview](./serialization/serialization-overview.md) page to understand the basics of serialization before learning how to serialize `NetworkObjects` and `NetworkBehaviours`.
45
56
`GameObject`, [`NetworkObject`](../../components/core/networkobject.md) and [`NetworkBehaviour`](../../components/core/networkbehaviour.md) aren't serializable types so they can't be used in [`RPC`s](../message-system/rpc.md) or [`NetworkVariable`s](../../basics/networkvariable.md) by default.
67

com.unity.netcode.gameobjects/Documentation~/advanced-topics/serialization/serialization-arrays.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Arrays and native containers
22

3-
It's recommended to read the [serialization overview](./serialization/serialization-overview.md) to better understand this documentation.
3+
> [!NOTE]
4+
> Read the [Serialization overview](./serialization/serialization-overview.md) page to understand the basics of serialization before learning how to serialize arrays and native containers.
45
56
Netcode for GameObjects has built-in serialization code for arrays of [C# value-type primitives](cprimitives.md), like `int[]`, and [Unity primitive types](unity-primitives.md). Any arrays of types that aren't handled by the built-in serialization code, such as custom types, need to be handled using a container class or structure that implements the [`INetworkSerializable`](inetworkserializable.md) interface.
67

com.unity.netcode.gameobjects/Documentation~/advanced-topics/serialization/serialization-overview.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
# Serialization overview
22

3-
Netcode uses a default serialization pipeline when using [`RPC`](../../rpc-landing.md)'s, [`NetworkVariable`](../../networkvariables-landing.md)s, or any other Netcode-related tasks that require serialization. The serialization pipeline looks like this:
3+
Netcode for GameObjects uses a default serialization pipeline when using [`RPC`](../../rpc-landing.md)'s, [`NetworkVariable`](../../networkvariables-landing.md)s, or any other Netcode-related tasks that require serialization. The serialization pipeline looks like this:
44

55
``
66
Custom Types => Built In Types => INetworkSerializable
77
``
88

9-
That is, when Netcode first gets hold of a type, it will check for any custom types that the user have registered for serialization, after that it will check if it's a built in type, such as a Vector3, float etc. These are handled by default. If not, it will check if the type inherits [`INetworkSerializable`](serialization/inetworkserializable.md), if it does, it will call it's write methods.
9+
When Netcode for GameObjects first receives a type, it checks for any custom types that you have registered for serialization, then it checks if it's a built-in type, such as a Vector3 or a float. These are handled by default. Otherwise, it checks if the type inherits [`INetworkSerializable`](inetworkserializable.md), and if it does, it calls its write methods.
1010

11-
By default, any type that satisfies the `unmanaged` generic constraint can be automatically serialized as RPC parameters. This includes all basic types (bool, byte, int, float, enum, etc) as well as any structs that has only these basic types.
11+
By default, any type that satisfies the unmanaged generic constraint can be automatically serialized as RPC parameters. This includes all basic types (bool, byte, int, float, enum, for example), as well as any structs that contain only these basic types.
1212

1313
Serialization and deserialization is done via the structs [`FastBufferWriter` and `FastBufferReader`](fastbufferwriter-fastbufferreader.md). These have methods for serializing individual types and methods for serializing packed numbers, but in particular provide a high-performance method called `WriteValue()/ReadValue()` (for Writers and Readers, respectively) that can extremely quickly write an entire unmanaged struct to a buffer.
1414

1515
`FastBufferWriter` and `FastBufferReader` also contain the functions `FastBufferWriter.WriteNetworkSerializable()` and `FastBufferReader.ReadNetworkSerializable` for writing and reading values that use the `INetworkSerializable` interface.
1616

17-
## Built in serialization
17+
## Built-in serialization
1818

1919
* [C# primitives](./cprimitives.md)
2020
* [Unity primitives](./unity-primitives.md)
@@ -29,7 +29,7 @@ Serialization and deserialization is done via the structs [`FastBufferWriter` an
2929
* [Customizing serialization](../custom-serialization.md)
3030
* [Custom NetworkVariable implementations](../../basics/custom-networkvariables.md)
3131

32-
## Other resources
32+
## Additional resources
3333

3434
* [NetworkObject serialization](./networkobject-serialization.md)
3535
* [FastBufferWriter and FastBufferReader](../fastbufferwriter-fastbufferreader.md)

com.unity.netcode.gameobjects/Documentation~/basics/custom-networkvariables.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
In addition to the standard [`NetworkVariable`s](networkvariable.md) available in Netcode for GameObjects, you can also create custom `NetworkVariable`s for advanced implementations. The `NetworkVariable` and `NetworkList` classes were created as `NetworkVariableBase` class implementation examples. While the `NetworkVariable<T>` class is considered production ready, you might run into scenarios where you have a more advanced implementation in mind. In this case, you can create your own custom implementation.
44

5-
It's recommended to read the [serialization overview](./serialization/serialization-overview.md) to understand how Netcode for GameObjects handles serialization.
5+
> [!NOTE]
6+
> Read the [Serialization overview](./serialization/serialization-overview.md) page to understand how Netcode for GameObjects handles serialization.
67
78
To create your own `NetworkVariableBase`-derived container, you should:
89

@@ -74,7 +75,7 @@ You can use `AreEqual` to determine if a value is different from the value that
7475
The type you use must be serializable according to the [supported types list](./networkvariable.md#supported-types). Each type needs its own serializer instantiated, so this step tells the codegen which types to create serializers for. Unity's code generator assumes that all `NetworkVariable` types exist as fields inside NetworkBehaviour types. This means that Unity only inspects fields inside NetworkBehaviour types to identify the types to create serializers for.
7576

7677
> [!NOTE]
77-
> These attributes won't generate delta serialization. If you would like to customize how deltas are sent when a custom value has partially changed, look into [`UserNetworkVariableSerialization`](../advanced-topics/custom-serialization.md#networkvariable).
78+
> These attributes won't generate delta serialization. If you would like to customize how deltas are sent when a custom value has partially changed, refer to [`UserNetworkVariableSerialization`](../advanced-topics/custom-serialization.md#networkvariable).
7879
7980
## Custom NetworkVariableBase example
8081

0 commit comments

Comments
 (0)