Skip to content

Commit

Permalink
Develop into main for 2.0.0-exp release (#1248)
Browse files Browse the repository at this point in the history
  • Loading branch information
jabbacakes authored Apr 8, 2024
2 parents b3a6fd2 + 8e5a729 commit 6f9f61a
Show file tree
Hide file tree
Showing 141 changed files with 14,641 additions and 140 deletions.
38 changes: 15 additions & 23 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,35 @@
The following Licenses cover all documentation and sample code in [this repository](https://github.com/Unity-Technologies/com.unity.multiplayer.docs) and website.
The following Licenses cover all documentation and sample code in [this repository](https://github.com/Unity-Technologies/com.unity.multiplayer.docs) and website.

## Documentation License

All documentation sections have licenses covering content for those Unity features and code:

| Documentation | License |
| -- | -- |
| [Netcode for GameObjects](https://docs-multiplayer.unity3d.com/docs/getting-started/about) | [MIT License](https://github.com/Unity-Technologies/com.unity.netcode.gameobjects) |
| [Netcode for GameObjects](https://docs-multiplayer.unity3d.com/docs/getting-started/about) | [Unity Companion License](https://unity3d.com/legal/licenses/Unity_Companion_License) |
| [Transport](https://docs-multiplayer.unity3d.com/docs/transport/introduction) | [Unity Companion License](https://unity3d.com/legal/licenses/Unity_Companion_License) |
| [Learn](https://docs-multiplayer.unity3d.com/docs/learn/introduction) | [UCL License](https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop/blob/v2.2.0/LICENSE.md) |
| [Learn](https://docs-multiplayer.unity3d.com/docs/learn/introduction) | [Unity Companion License](https://unity3d.com/legal/licenses/Unity_Companion_License) |

Documentation site files and markdown content outside of these features is covered under the MIT License:
Documentation site files and markdown content outside of these features are also covered under the Unity Companion License:

MIT License

Copyright (c) 2021 Unity Technologies

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
Licensed under the Unity Companion License for Unity-dependent projects (see https://unity3d.com/legal/licenses/unity_companion_license).

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions.

## Netcode for GameObjects License

The [Netcode for GameObjects repository](https://github.com/Unity-Technologies/com.unity.netcode.gameobjects) and code are under the MIT License.

MIT License
The [Netcode for GameObjects repository](https://github.com/Unity-Technologies/com.unity.netcode.gameobjects) and code are under the Unity Companion License (UCL).

Copyright (c) 2020 Unity Technologies

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
UCL License
Netcode for GameObjects © 2021-2024 Unity Technologies

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
Licensed under the Unity Companion License for Unity-dependent projects (see https://unity3d.com/legal/licenses/unity_companion_license).

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions.

## Multiplayer Sample Co-op License

The [Multiplayer Sample Co-op respository](https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop) and code are under a UCL License.
The [Multiplayer Sample Co-op respository](https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop) and code are under a UCL License.

UCL License
Boss Room: Multiplayer Sample Co-op © 2021 Unity Technologies
Expand All @@ -49,7 +40,7 @@ Unless expressly provided otherwise, the Software under this license is made ava

## Multiplayer Bitesize Sample License

The [Multiplayer Bitesize Sample respository](https://github.com/Unity-Technologies/com.unity.multiplayer.samples.bitesize) and code are under a UCL License.
The [Multiplayer Bitesize Sample respository](https://github.com/Unity-Technologies/com.unity.multiplayer.samples.bitesize) and code are under a UCL License.

UCL License
Boss Room: Multiplayer Bitesize Sample© 2021 Unity Technologies
Expand All @@ -62,8 +53,9 @@ Unless expressly provided otherwise, the Software under this license is made ava

Transport code is under a [Unity Companion License](https://unity3d.com/legal/licenses/Unity_Companion_License). The repository is currently private.

UCL License
Unity Transport copyright © 2018 Unity Technologies ApS

Licensed under the Unity Companion License for Unity-dependent projects--see Unity Companion License.
Licensed under the Unity Companion License for Unity-dependent projects (see https://unity3d.com/legal/licenses/unity_companion_license).

Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions.
2 changes: 1 addition & 1 deletion docs/advanced-topics/physics.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Add the ClientNetworkTransform component to your GameObject first. Otherwise the

## Physics and latency

A common issue with physics in multiplayer games is lag and how objects update on basically different timelines. For example, a player would be on a timeline thats offset by the network latency relative to your servers objects. One way to prepare for this is to test your game with artificial lag. You might catch some weird delayed collisions that would otherwise make it into production.
A common issue with physics in multiplayer games is lag and how objects update on basically different timelines. For example, a player would be on a timeline that's offset by the network latency relative to your server's objects. One way to prepare for this is to test your game with artificial lag. You might catch some weird delayed collisions that would otherwise make it into production.

The ClientDriven [bitesize sample](../learn/bitesize/bitesize-clientdriven.md) addresses this by manually adding forces server-side to offer a buffer before an actual collision, but it still feels wobbly at times. However, this isn't really a solution.

Expand Down
233 changes: 233 additions & 0 deletions docs/basics/deferred-despawning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
---
id: deferred-despawning
title: Deferred despawning
---

:::info Distributed authority only

Deferred despawning is only available for games using a [distributed authority topology](../terms-concepts/distributed-authority.md).

:::

In addition to the visual latency issues described on the [spawning synchronization page](spawning-synchronization.md), networked games also experience latency issues when despawning objects. In [client-server](../terms-concepts/client-server.md) contexts, these problems are typically addressed using client prediction models, but in a distributed authority context there is a simpler alternative solution: deferred despawning.

## Why deferred despawning

Issues with despawning occur when objects are despawned too early. The client that owns the projectile detects a collision, triggers any local animations, and despawns the projectile locally. For the player being hit, they see the projectile despawn before it reaches them and animations can appear to trigger at the wrong point in time. This can be seen in the diagram below.

![Without deferred despawning](/img/without-deferred-despawning.jpg)

Deferred despawning allows you to add a tick-based delay to a NetworkObject prior to despawning it locally. The deferred despawn tick value is then added to the `DestroyObjectMessage` so that other clients, upon receiving the message, defer processing the destroy message until the specified tick value has been reached. The results of this deferred despawn adjustment can be seen in the diagram below.

![With deferred despawning](/img/with-deferred-despawning.jpg)

Deferred despawning allows non-owner instances of an object to complete their interpolation towards the last transform state update before despawning the object. Even though non-owner clients can be visually latent by several network ticks behind the authority, all clients end up with the same visual experience since NetworkTransform deltas are tick synchronized.

## Implementing deferred despawning

Implementing deferred despawning is a three-step process, as described in the diagram below.

![Implementing deferred despawning](/img/implementing-deferred-despawning.jpg)

The process above is broken down into two steps that are performed on the authority instance, and one step performed on the non-authority instance(s).

|Authority instance|Non-authority instance(s)|
|---|---|
|1. Invoke the `NetworkObject.DeferDespawn` method while providing the number of ticks to offset despawning by on non-authority instance(s), relative to the local client's current known network tick.<br/> 2. If overridden, handle any changes to state (i.e. NetworkVariables) when `NetworkBehaviour.OnDeferringDespawn` is invoked.|1. Use any updated states to synchronize the visual portion of a deferred despawn (for example, starting a particle system to represent the point of impact).|

### Deferred despawning example

Below is a basic example demonstrating how deferred despawning can be used to visually synchronize a projectile's impact with explosion effects:

```
public class ExplodingProjectile : NetworkBehaviour
{
// The explosion network prefab
public GameObject ExplosionPrefab;
public int DespawnTickOffset = 4;
private ExplosionFx m_SpawnedExplosion;
// Permission are always owner write and everyone read in distributed authority
// Authority assigns this value after spawning the ExplosionFx within the overridden
// OnDeferringDespawn method prior to the local ExplodingPrrojectile is despawned
// locally.
private NetworkVariable<NetworkBehaviourReference> m_ExplosionFx = new NetworkVariable<NetworkBehaviourReference>();
public override void OnNetworkSpawn()
{
if (!HasAuthority)
{
m_ExplosionFx.OnValueChanged += OnExplosionFxChanged;
}
base.OnNetworkSpawn();
}
private void OnCollisionEnter(Collision collision)
{
if (!IsSpawned || !HasAuthority)
{
return;
}
// Typically you would want to check what you hit
// to make sure you want to "explode" the projectile
// first. This example assumes that a check was performed.
// Start with the projectile's position
var explodePoint = transform.position;
if (collision.contacts.Length > 0 )
{
// Example purposes, just use the first contact
explodePoint = collision.contacts[0].point;
}
HandleExplosion(explodePoint);
}
private void HandleExplosion(Vector3 explodePoint)
{
// Example purposes only, we recommend using object pools
// using an INetworkPrefabInstanceHandler implementation
// and registering that with the NetworkManager.PrefabHandler.
var instance = Instantiate(ExplosionPrefab);
// position the explosion
instance.transform.position = explodePoint;
// Assign this for later use (example purposes)
m_SpawnedExplosion = instance.GetComponent<ExplosionFx>();
// Spawn the explosion
var instanceObj = instance.GetComponent<NetworkObject>();
instanceObj.Spawn();
// Defer the despawning of the projectile instance
NetworkObject.DeferDespawn(DespawnTickOffset);
// The local instance should be despawned at this point
}
/// <summary>
/// Invoked on the authority side when it is deferring the
/// despawning of the NetworkObject.
/// </summary>
/// <remarks>
/// This is a good time to set any NetworkVariable states as
/// they will be sent to clients prior to the defer despawn message.
/// </remarks>
/// <param name="despawnTick">the final future network tick
/// non-authority instances will despawn the clone instance.</param>
public override void OnDeferringDespawn(int despawnTick)
{
// This lets the non-authority instances know what ExplosionFx instance is
// associated with this NetworkObject.
m_ExplosionFx = new NetworkVariable<NetworkBehaviourReference>(m_SpawnedExplosion);
// Apply any other state updates here
base.OnDeferringDespawn(despawnTick);
}
/// <summary>
/// Non-authority registers for this and acquires the ExplosionFX
/// of the network prefab spawned.
/// </summary>
private void OnExplosionFxChanged(NetworkBehaviourReference previous, NetworkBehaviourReference current)
{
// If possible, get the ExplosionFx component
current.TryGet(out m_SpawnedExplosion);
}
public override void OnNetworkDespawn()
{
// When non-authority instances finally despawn,
// the explosion FX will begin playing.
if (!HasAuthority)
{
if (m_SpawnedExplosion)
{
m_SpawnedExplosion.SetParticlePlayingState(true);
}
m_ExplosionFx.OnValueChanged -= OnExplosionFxChanged;
}
base.OnNetworkDespawn();
}
}
```

The pseudo script above excludes the motion of the projectile, but makes the assumption that authority is moving the projectile and that when the projectile impacts a valid object, the `OnCollisionEnter` method will be invoked.

Authority instance|Non-authority instance(s)|
|---|---|
|1. Move until collision (excluded from the above example)<br/> 2. Upon collision: instantiate ExplosionFX, position ExplosionFX, acquire the ExplosionFX component, spawn the ExplosionFX, defer despawning the projectile<br/> 3. When deferring despawning the projectile, assign the NetworkBehaviourReference to the ExplosionFX<br/> 4. Despawn locally (happens automatically at end of the DeferDespawn)|1. When spawned, register changes to the m_ExplosionFX NetworkVariable<br/> 2. Continue to interpolate towards last updated position (handled by NetworkTransform)<br/> 3. When m_ExplosionFX NetworkVariable changes, assign the local m_SpawnExplosion ExplosionFX component of the explosion associated with the current projectile instance (to be used when despawned)<br/> 4.When despawned, start the ExplosionFX particle system via m_SpawnExplosion|

The non-authority instance still spawns the ExplosionFX NetworkObject at the same relative time frame as the authority, however it doesn't start its particle system until the local non-authority projectile instance is despawned. Since the projectile has had its despawn deferred until a future network tick, the non-authority instance interpolates up to its last updated position from the authority side and then shortly (in milliseconds) after is despawned and the explosion particle system started.

:::info Example purposes only

The spawning explosion FX example above is only for example purposes and would be less bandwidth and processor intensive if you used a local particle FX pool that you pull from and began playing on both the authority and non-authority sides when the object in question is despawned. The same deferred despawn principles would be used without the need to spawn an additional object. However, providing the spawned explosion example also covers other scenarios where spawning is required.

:::

For example purposes, the below script is all that you would need to control starting and stopping the explosion particle system:

```
public class ExplosionFx : NetworkBehaviour
{
public ParticleSystem ParticleSystem;
private void OnEnable()
{
// In the event a pool is used, it is always good to
// make sure the particle system is not playing
SetParticlePlayingState();
}
public override void OnNetworkSpawn()
{
// Authority starts the particle system (locally) when spawned
if (HasAuthority)
{
SetParticlePlayingState(true);
}
base.OnNetworkSpawn();
}
/// <summary>
/// Used to start/stop the particle system
/// Non-Authority starts this when its associated projectile
/// is finally despawned
/// </summary>
public void SetParticlePlayingState(bool isPlaying = false)
{
if (ParticleSystem)
{
if(isPlaying)
{
ParticleSystem.Play();
}
else
{
ParticleSystem.Stop();
}
}
}
}
```

Note that the authority automatically starts the particle system upon being spawned. Non-authority instances are started by their paired projectile when despawned at the end of the deferred despawn defined network tick.
1 change: 1 addition & 0 deletions docs/basics/networkobject.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ This will process the currently opened scene as well.

The `NetworkObject.SpawnWithObservers` property (default is true) provides you with the ability to spawn a `NetworkObject` with no initial observers. This is the recommended alternative to using `NetworkObject.CheckObjectVisibility` when you just want it to be applied globally to all clients (only when spawning an instance of the `NetworkObject` in question). If you want more precise per-client control then `NetworkObject.CheckObjectVisibility` is recommended. `NetworkObject.SpawnWithObservers` is only applied upon the initial server-side spawning and once spawned it has no impact on object visibility.


## Transform synchronization

![image](/img/NetworkObject-TransformSynchronization.png)
Expand Down
Loading

0 comments on commit 6f9f61a

Please sign in to comment.