Skip to content

Commit

Permalink
Develop into main (#1327)
Browse files Browse the repository at this point in the history
Co-authored-by: Noel Stephens <[email protected]>
Co-authored-by: Vic Cooper <[email protected]>
Co-authored-by: Dominick <[email protected]>
Co-authored-by: Rémi MACH <[email protected]>
Co-authored-by: LagowiecDev <[email protected]>
Co-authored-by: amanda-butler-unity <[email protected]>
Co-authored-by: Griffin of Innatical <[email protected]>
Co-authored-by: Christopher Pope <[email protected]>
Co-authored-by: Steve Diniro <[email protected]>
Co-authored-by: s-omeilia-unity <[email protected]>
Co-authored-by: Alex Martin <[email protected]>
Co-authored-by: Monaxys <[email protected]>
Co-authored-by: Flap27 <[email protected]>
Co-authored-by: NRTnarathip <[email protected]>
Co-authored-by: Elfi0Kuhndorf <[email protected]>
Co-authored-by: CodeSmile <[email protected]>
Co-authored-by: Frank Luong <[email protected]>
Co-authored-by: Sue Arkin <[email protected]>
Co-authored-by: Johann Ruwet <[email protected]>
Co-authored-by: KreutzerCode <[email protected]>
  • Loading branch information
1 parent 9f12a41 commit b2facd9
Show file tree
Hide file tree
Showing 27 changed files with 393 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ If you have a type you wish to serialize that you know is compatible with this m
public NetworkVariable<ForceNetworkSerializeByMemcpy<Guid>> GuidVar;
```

f:::caution
:::caution
Take care with using `INetworkSerializeByMemcpy`, and especially `ForceNetworkSerializeByMemcpy`, because not all unmanaged structs are actually compatible with this type of serialization. Anything that includes pointer types (including Native Collections like `NativeArray<>`) won't function correctly when serialized this way, and will likely cause memory corruption or crashes on the receiving side.
:::
8 changes: 6 additions & 2 deletions docs/basics/connection-approval.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ id: connection-approval
title: Connection approval
---

With every new connection, Netcode for GameObjects performs a handshake in addition to handshakes done by the transport. This ensures that the NetworkConfig on the client matches the server's NetworkConfig. You can enable ConnectionApproval in the NetworkManager or via code by setting `NetworkManager.NetworkConfig.ConnectionApproval` to `true`. Connection approval allows you to decide, on a per connection basis, whether to allow a connection. You can also use connection approval to specify the player Prefab to create, allowing you to override the default NetworkManager-defined player Prefab on a per player basis.
Connection approval allows you to decide for every new client connection attempt whether to allow or deny the client to connect.

When you set the ConnectionApproval property of the NetworkManager to true, Netcode for GameObjects checks to make sure the `NetworkManager.ConnectionApprovalCallback` has been assigned. If assigned, the connection approval process is used for connecting clients to decide whether to allow a connection or deny it. If you don't assign the `NetworkManager.ConnectionApprovalCallback` (even with the `NetworkManager.ConnectionApprovalCallback` set to `true`), Netcode for GameObjects uses basic authentication for the user, which automatically authorizes and assigns the default player Prefab.
You can also send additional payload data via connection approval to initialize the client. For instance you can use this data to have a client specify a custom player Prefab (see example below).

You have to enable ConnectionApproval in the NetworkManager Inspector or by setting `NetworkManager.NetworkConfig.ConnectionApproval = true` in a script before starting the host/server. If connection approval is not enabled, the `NetworkManager.ConnectionApprovalCallback` is not invoked.

In both cases clients also have to pass internal authentication, to confirm that their NetworkConfig matches that of the server.

## Server-side connection approval example

Expand Down
31 changes: 29 additions & 2 deletions docs/basics/networkobject.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ When you want to despawn and destroy the owner but you don't want to destroy a s

## Player NetworkObjects

Player objects are an optional feature in Netcode for GameObjects that you can use to assign a networked object to a specific client. A client can always only have at most one player object.
Player objects are an optional feature in Netcode for GameObjects that you can use to assign a networked object to a specific client. A client can only have at most one player object.

If you want a client to control more than one NetworkObject, use the ownership methods described above under the ownership section.

Expand All @@ -88,6 +88,33 @@ GetComponent<NetworkObject>().SpawnAsPlayerObject(clientId);

If the player already had a prefab instance assigned, then the client owns the NetworkObject of that prefab instance unless there's additional server-side specific user code that removes or changes the ownership.

### Defining defaults for PlayerObjects

If you're using `UnityEngine.InputSystem.PlayerInput` or `UnityEngine.PhysicsModule.CharacterController` components on your player prefab(s), you should disable them by default and only enable them for the local client's PlayerObject. Otherwise, you may get events from the most recently instantiated player prefab instance, even if it isn't the local client instance.

You can disable these components in the **Inspector** view on the prefab itself, or disable them during `Awake` in one of your `NetworkBehaviour` components. Then you can enable the components only on the owner's instance using code like the example below:

```
PlayerInput m_PlayerInput;
private void Awake()
{
m_PlayerInput = GetComponent<PlayerInput>();
m_PlayerInput.enabled = false;
}
public override void OnNetworkSpawn()
{
m_PlayerInput.enabled = IsOwner;
base.OnNetworkSpawn();
}
public override void OnNetworkDespawn()
{
m_PlayerInput.enabled = false;
base.OnNetworkDespawn();
}
```

### Finding PlayerObjects

To find a PlayerObject for a specific client ID, you can use the following methods:
Expand Down Expand Up @@ -140,7 +167,7 @@ If you're planning to use a NetworkTransform, then you always want to make sure

When a GameObject is instantiated, it gets instantiated in the current active scene. However, sometimes you might find that you want to change the currently active scene and would like specific NetworkObject instances to automatically migrate to the newly assigned active scene. While you could keep a list or table of the NetworkObject instances and write the code/logic to migrate them into a newly assigned active scene, this can be time consuming and become complicated depending on project size and complexity. The alternate and recommended way to handle this is by enabling the **Active Scene Synchronization** property of each NetworkObject you want to automatically migrate into any newly assigned scene. This property defaults to disabled.

Refer to the [NetworkSceneManager active scene synchronization](../basics/scenemanagement/using-networkscenemanager#active-scene-synchronization) page for more details.
Refer to the [NetworkSceneManager active scene synchronization](../scenemanagement/using-networkscenemanager#active-scene-synchronization) page for more details.

## Scene migration synchronization

Expand Down
16 changes: 11 additions & 5 deletions docs/basics/networkvariable.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ Additionally, any type that has a managed type is itself a managed type - so a s

Finally, while managed `INetworkSerializable` types are serialized in-place (and thus don't incur allocations for simple value updates), C# arrays and managed types serialized through custom serialization are **not** serialized in-place, and will incur an allocation on every update.

### Using collections with `NetworkVariable`s

You can use `NetworkVariable`s with both managed and unmanaged collections, but you need to call `NetworkVariable<T>.CheckDirtyState()` after making changes to a collection (or items in a collection) for those changes to be detected. Then the [`OnValueChanged`](#onvaluechanged-example) event will trigger, if subscribed locally, and by the end of the frame the rest of the clients and server will be synchronized with the detected change(s).

`NetworkVariable<T>.CheckDirtyState()` checks every item in a collection, including recursively nested collections, which can have a significant impact on performance if collections are large. If you're making multiple changes to a collection, you only need to call `NetworkVariable<T>.CheckDirtyState()` once after all changes are complete, rather than calling it after each change.

## Synchronization and notification example

The following client-server example shows how the initial `NetworkVariable` synchronization has already occurred by the time `OnNetworkSpawn` is invoked. It also shows how subscribing to `NetworkVariable.OnValueChanged` within `OnNetworkSpawn` provides notifications for any changes to `m_SomeValue.Value` that occur.
Expand Down Expand Up @@ -244,7 +250,7 @@ Owner writer permissions are owner-only.

There are two options for reading a `NetworkVariable.Value`:

- **Everyone(default)**: both owners and non-owners of the NetworkObject can read the value.
- **Everyone (default)**: both owners and non-owners of the NetworkObject can read the value.
- This is useful for global states that all clients should be aware of, such as player scores, health, or any other state that all clients should know about.
- We provided an example of maintaining a door's open or closed state using the everyone permission.
- **Owner**: only the owner of the NetworkObject and the server can read the value.
Expand All @@ -254,9 +260,9 @@ There are two options for reading a `NetworkVariable.Value`:

There are two options for writing a `NetworkVariable.Value`:

- **Server(default)**: the server is the only one that can write the value.
- **Server**: the server is the only one that can write the value. This is the default for [client-server contexts](../terms-concepts/client-server.md).
- This is useful for server-side specific states that all clients should be aware of but can't change, such as an NPC's status or some global world environment state (that is, is it night or day time).
- **Owner**: only the owner of the NetworkObject can write to the value.
- **Owner**: only the owner of the NetworkObject can write to the value. This is the default for [distributed authority contexts](../terms-concepts/distributed-authority.md).
- This is useful if your `NetworkVariable` represents something specific to the client's player that only the owning client should be able to set, such as a player's skin or other cosmetics.

### Permissions example
Expand Down Expand Up @@ -349,7 +355,7 @@ public class PlayerState : NetworkBehaviour
void Awake()
{
//NetworkList can't be initialized at declaration time like NetworkVariable. It must be initialized in Awake instead.
//If you do initialize at declaration, you will run into Memmory leak errors.
//If you do initialize at declaration, you will run into memory leak errors.
TeamAreaWeaponBoosters = new NetworkList<AreaWeaponBooster>();
}

Expand Down Expand Up @@ -467,7 +473,7 @@ public struct AreaWeaponBooster : INetworkSerializable, System.IEquatable<AreaWe

public bool Equals(AreaWeaponBooster other)
{
return other.Equals(this) && Radius == other.Radius && Location == other.Location;
return other.ApplyWeaponBooster.Equals(ApplyWeaponBooster) && Radius == other.Radius && Location == other.Location;
}
}
```
Expand Down
Loading

0 comments on commit b2facd9

Please sign in to comment.