Skip to content

Add NGO 1.1.0 documentation #839

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/advanced-topics/inscene_parenting_player.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ public class ParentPlayerToInSceneNetworkObject : NetworkBehaviour
// As long as the client (player) is in the connected clients list
if (NetworkManager.ConnectedClients.ContainsKey(clientId))
{
// Set the player as a child of this in-scene placed NetworkObject
NetworkManager.ConnectedClients[clientId].PlayerObject.transform.parent = transform;
// Set the player as a child of this in-scene placed NetworkObject
// We parent in local space by setting the WorldPositionStays value to false
NetworkManager.ConnectedClients[clientId].PlayerObject.TrySetParent(NetworkObject, false);
}
}
}
Expand Down Expand Up @@ -83,5 +84,5 @@ You should place this script on your in-scene placed `NetworkObject` (i.e. the f


:::note
Remove any parenting code you might have had from your player prefab before using the above script.
Remove any parenting code you might have had from your player prefab before using the above script. Depending upon your project's goals, you might be parenting all players under the same in-scene placed `NetworkObject` or you might intend to have each player parenting unique. If you want each player to be parented under a unique in-scene placed `NetworkObject` then you will need to have the same number of in-scene placed `NetworkObject`s as your maximum allowed players per game session. The above example will only parent all players under the same in-scene placed `NetworkObject`. You could extend the above example by migrating the scene event code into an in-scene placed `NetworkObject` that manages the parenting of players (i,e. name it something like `PlayerSpawnManager`) as they connect, make the `SetPlayerParent` method public, and add all in-scene placed `NetworkObject`s to a public list of GameObjects that the `PlayerSpawnManager` will reference and assign player's to as they connect while also freeing in-scene placed `NetworkObject`s as players disconnect during a game session.
:::
14 changes: 12 additions & 2 deletions docs/advanced-topics/networkobject-parenting.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ Vehicle (GameObject->NetworkObject)
This would be considered an invalid parenting and would be reverted.

### Mildly Complex Valid Example:
In order to resolve the previous invalid parenting issue, we would need to add a `NetworkObjet` component to the seats. This means we would need to:
In order to resolve the previous invalid parenting issue, we would need to add a `NetworkObject` component to the seats. This means we would need to:
1. Spawn the vehicle and the seats:
```
Sun
Expand Down Expand Up @@ -185,8 +185,18 @@ Vehicle (GameObject->NetworkObject)
└─Seat2 (GameObject->NetworkObject)
```

### Parenting & Transform Synchronization
It is important to understand that without the use of a `NetworkTransform` clients are only synchronized with the transform values when:
- A client is being synchronized with the NetworkObject in question:
- During the client's first synchronization after a client has their connection approved.
- When a server spawns a new `NetworkObject`.
- A `NetworkObject` has been parented _(or a parent removed)_.
- The server can override the `NetworkBehaviour.OnNetworkObjectParentChanged` method and adjust the transform values when that is invoked.
- These transform changes will be synchronized with clients via the `ParentSyncMessage`


:::note Optional Auto Synchronized Parenting
The Auto Object Parent Sync property of NetworkObject, enabled by default, allows you to disable automatic parent change synchronization in the event you want to implement your own parenting solution for one or more NetworkObjects.
The Auto Object Parent Sync property of a `NetworkObject`, enabled by default, allows you to disable automatic parent change synchronization in the event you want to implement your own parenting solution for one or more NetworkObjects. It is important to understand that disabling the Auto Object Parent Sync option of a `NetworkObject` will treat the `NetworkObject`'s transform synchronization with *clients* as if its parent is the hierarchy root _(i.e. null)_.
:::


30 changes: 27 additions & 3 deletions docs/basics/scenemanagement/inscene-placed-networkobjects.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,30 @@ In-scene placed `NetworkObject`s follow the same parenting rules as [dynamically
- Under this scenario, you would want to use a hybrid approach where the in-scene placed `NetworkObject` dynamically spawns the item to be picked up.
- If you plan on using a bootstrap scene usage pattern where you use additive scene loading and unloading with no full scene-migration(s), then it is "OK" to parent in-scene placed NetworkObjects.

:::warning
Parenting in-scene placed `NetworkObject`s under `GameObject`s with no `NetworkObject` component will currently synchronize the child `NetworkObject` as if it is in world space on the client side. To work around this particular issue you should add a `NetworkTransform` to the child and enable local space synchronization.
:::
### Auto Object Parent Sync Option & Parenting
Already parented in-scene placed `NetworkObject`s Auto Object Parent Sync Usage:

- When disabled, the NetworkObject ignores its parent and considers all of its transform values as being world space synchronized (i.e. no matter where you move or rotate its parent, it will maintain its current position and rotation)
- Typically, when disabling this you need to handle synchronizing the client either through your own custom messages or RPCS or add a NetworkTransform component to it. This is only useful if you want to have some global parent that might shift or have transform values that you don't want to impact the `NetworkObject` in question.
- When enabled, the NetworkObject is aware of its parent and will treat all of its transform values as being local space synchronized.
- _This also applies to being pre-parented under a `GameObject` with no `NetworkObject` component._

:::note
_**The caveat to the above is scale**:_
Scale is treated always as local space relative for pre-parented in-scene placed `NetworkObjects`. <br />

*For dynamically spawned NetworkObjects:* <br />
It depends upon what WorldPositionStays value you use when parenting the NetworkObject in question.<br />
WorldPositionStays = true: Everything is world space relative. _(default)_<br />
WorldPositionStays = false: Everything is local space relative. _(children offset relative to the parent)_<br />
:::


### Parenting & Transform Synchronization
It is important to understand that without the use of a `NetworkTransform` clients are only synchronized with the transform values when:
- A client is being synchronized with the NetworkObject in question:
- During the client's first synchronization after a client has their connection approved.
- When a server spawns a new NetworkObject.
- A NetworkObject has been parented (or a parent removed).
- The server can override the `NetworkBehaviour.OnNetworkObjectParentChanged` method and adjust the transform values when that is invoked.
- These transform changes will be synchronized with clients via the `ParentSyncMessage`
6 changes: 5 additions & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,13 @@ module.exports = {
lastVersion: "current",
versions: {
current: {
label: '1.0.0',
label: '1.1.0',
path: 'current',
},
'1.0.0': {
label: '1.0.0',
path: '1.0.0',
},
'0.1.0': {
label: '0.1.0',
path: '0.1.0',
Expand Down
55 changes: 55 additions & 0 deletions versioned_docs/version-1.0.0/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
id: about
title: About Netcode for GameObjects
description: Learn more about the available APIs for Unity Multiplayer Networking, including Netcode for GameObjects and Transport.
---

Netcode for GameObjects (Netcode) is a high-level networking library built for Unity for you to abstract networking logic. It enables you to send GameObjects and world data across a networking session to multiplayer players at once. With Netcode, you can focus on building your game instead of low-level protocols and networking frameworks.

To learn more about Netcode for GameObjects functionality and capabilities, explore the content below:

<div class="table-columns-plain" >

| Getting Started | Hello World and Golden Paths | Education and Samples |
| -- | -- | -- |
| [Install Unity Netcode](installation/installation.md)<br/>[Migration from UNet to Netcode](installation/migratingfromUNet.md)<br/>[Upgrade to Unity Netcode Package](installation/migratingfrommlapi.md) | [Your First Networked Game](tutorials/helloworld.md)<br/>[Module One](tutorials/goldenpath_series/gp_module_one.md)<br/>[Module Two](tutorials/goldenpath_series/gp_module_two.md)<br/>| [Boss Room](learn/bossroom/getting-started-boss-room.md)<br/>[Bite Size Samples](learn/bitesize/bitesize-introduction.md)<br/>[Dilmer's Tutorials](learn/dilmer/dilmer-video.md) |

</div>

<div class="table-columns-plain" >

| Core Concepts | Debugging | Terminology and FAQs |
| -- | -- | -- |
| [Networking](basics/connection-approval.md)<br/>[Components](components/networkmanager.md)<br/>[Objects](basics/object-spawning.md)<br/>[Messaging System](advanced-topics/messaging-system.md)<br/>[Serialization](advanced-topics/serialization/serialization-intro.md)<br/>[Scenes](basics/scenemanagement/scene-management-overview.md) | [Logging](basics/logging.md)<br/>[Troubleshooting](troubleshooting/troubleshooting.md)<br/>[Error Messages](troubleshooting/error-messages.md) | [High Level Terminology](reference/glossary/high-level-terminology.md)<br/>[Multiplayer Game Architecture](learn/multiplayer_game_arch_intro.md)<br/>[FAQs](learn/faq.md) |

</div>

Don't forget to check out our [Release Notes](https://docs-multiplayer.unity3d.com/releases/introduction) and [APIs](api/introduction.md)!

## Before you begin

Netcode supports the following versions:
* Unity 2020.3, 2021.1, 2021.2, and 2021.3
* Mono and IL2CPP [Scripting Backends](https://docs.unity3d.com/Manual/scripting-backends.html)

Netcode supports the following platforms:
* Windows, MacOS, and Linux
* iOS and Android
* XR platforms running on Windows, Android, and iOS operating systems
* Most [**closed platforms**](https://unity.com/platform-installation), such as consoles. Contact us for more information about specific closed platforms.
* When working with consoles (such as PlayStation, Xbox, or Nintendo Switch), there may be Netcode-specific policies you should be aware of while testing and before launching your game live. Refer to the console's internal documentation for more information. This content is typically protected by NDA.

:::caution Using WebGL
Netcode does not support the WebGL platform because it does not allow access to IP Sockets.

There are third party transports provided by the community that may enable you to use Netcode on WebGL platforms. A list of these transports are found [here](https://github.com/Unity-Technologies/multiplayer-community-contributions#transports).

Use with caution:
* You may encounter bugs and issues while using Netcode on WebGL, and we will not prioritize fixing those issues.
* The server or host cannot be a WebGL client, but a Desktop or Mobile build.
* You may experience **increased** latency and jitter because of the TCP protocol used by WebSockets.
:::

:::unity Content Licenses
This is free under the permissive MIT [Licenses](/reference/license) by Unity and the Netcode collaborators. Netcode is open source with no attached costs or limitations, so you can develop features alongside Unity.
:::
21 changes: 21 additions & 0 deletions versioned_docs/version-1.0.0/advanced-topics/bufferserializer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
id: bufferserializer
title: BufferSerializer
sidebar_label: BufferSerializer
---

`BufferSerializer<TReaderWriter>` is the bi-directional serializer primarily used for serializing within [`INetworkSerializable`](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:

- Rather than writing separate methods for serializing and deserializing, `BufferSerializer<TReaderWriter>` allows writing a single method that can handle both operations, which reduces the possibility of a mismatch between the two
- `BufferSerializer<TReaderWriter>` does bound checking on every read and write by default, making it easier to avoid mistakes around manual bounds checking required by `FastBufferWriter` and `FastBufferReader`

These aren't without downsides, however:

- `BufferSerializer<TReaderWriter>` has to operate on an existing mutable value due to its bi-directional nature, which means values like `List<T>.Count` have to be stored to a local variable before writing.
- `BufferSerializer<TReaderWriter>` is slightly slower than `FastBufferReader` and `FastBufferWriter` due to both the extra pass-through method calls and the mandatory bounds checking on each write.
- `BufferSerializer<TReaderWriter>` do not support any form of packed reads and writes.

However, when those downsides are unreasonable, `BufferSerializer<TReaderWriter>` offers two ways to perform more optimal serialization for either performance or bandwidth usage:

- For performance, you can use `PreCheck(int amount)` followed by `SerializeValuePreChecked()` to perform bounds checking for multiple fields at once.
- For both performance and bandwidth usage, you can obtain the wrapped underlying reader/writer via `serializer.GetFastBufferReader()` when `serializer.IsReader` is `true`, and `serializer.GetFastBufferWriter()` when `serializer.IsWriter` is `true`. These provide micro-performance improvements by removing a level of indirection, and also give you a type you can use with `BytePacker` and `ByteUnpacker`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
id: custom-serialization
title: Custom Serialization
---

When using `RPC`'s, `NetworkVariable`'s or any other Netcode for GameObjects (Netcode) related task that requires serialization. The Netcode uses a default serialization pipeline that looks like this:

``
Custom Types => Built In Types => INetworkSerializable
``

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`, if it does, it will call it's write methods.

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 contains only these basic types.

With this flow, you can override **ALL** serialization for **ALL** types, even built in types, and with the API provided, it can even be done with types that you have not defined yourself, those who are behind a 3rd party wall, such as .NET types.

To register a custom type, or override an already handled type, you need to create extension methods for `FastBufferReader.ReadValueSafe()` and `FastBufferWriter.WriteValueSafe()`:

```csharp
// Tells the Netcode how to serialize and deserialize Url in the future.
// The class name doesn't matter here.
public static class SerializationExtensions
{
public static void ReadValueSafe(this FastBufferReader reader, out Url value)
{
reader.ReadValueSafe(out string val);
value = new Url(val);
}

public static void WriteValueSafe(this FastBufferWriter writer, in Url value)
{
writer.WriteValueSafe(instance.Value);
}
}
```

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

You can also optionally use the same method to add support for `BufferSerializer<TReaderWriter>.SerializeValue()`, if you wish, which will make this type readily available within [`INetworkSerializable`](/advanced-topics/serialization/inetworkserializable.md) types:

```c#
// The class name doesn't matter here.
public static class SerializationExtensions
{
public static void SerializeValue<TReaderWriter>(this BufferSerializer<TReaderWriter> serializer, ref Url value) where TReaderWriter: IReaderWriter
{
if (serializer.IsReader)
{
value = new Url();
}
serializer.SerializeValue(ref value.Value);
}
}
```

Additionally, you can also add extensions for `FastBufferReader.ReadValue()`, `FastBufferWriter.WriteValue()`, and `BufferSerializer<TReaderWriter>.SerializeValuePreChecked()` to provide more optimal implementations for manual serialization using `FastBufferReader.TryBeginRead()`, `FastBufferWriter.TryBeginWrite()`, and `BufferSerializer<TReaderWriter>.PreCheck()`, respectively. However, none of these will be used for serializing RPCs - only `ReadValueSafe` and `WriteValueSafe` are used.
Loading