com.unity.netcode.gameobjects@1.0.0-pre.2

# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com).

## [1.0.0-pre.2] - 2020-12-20

### Added

- Associated Known Issues for the 1.0.0-pre.1 release in the changelog

### Changed

- Updated label for `1.0.0-pre.1` changelog section

## [1.0.0-pre.1] - 2020-12-20

### Added

- Added `ClientNetworkTransform` sample to the SDK package (#1168)
- Added `Bootstrap` sample to the SDK package (#1140)
- Enhanced `NetworkSceneManager` implementation with additive scene loading capabilities (#1080, #955, #913)
  - `NetworkSceneManager.OnSceneEvent` provides improved scene event notificaitons
- Enhanced `NetworkTransform` implementation with per axis/component based and threshold based state replication (#1042, #1055, #1061, #1084, #1101)
- Added a jitter-resistent `BufferedLinearInterpolator<T>` for `NetworkTransform` (#1060)
- Implemented `NetworkPrefabHandler` that provides support for object pooling and `NetworkPrefab` overrides (#1073, #1004, #977, #905,#749, #727)
- Implemented auto `NetworkObject` transform parent synchronization at runtime over the network (#855)
- Adopted Unity C# Coding Standards in the codebase with `.editorconfig` ruleset (#666, #670)
- When a client tries to spawn a `NetworkObject` an exception is thrown to indicate unsupported behavior. (#981)
- Added a `NetworkTime` and `NetworkTickSystem` which allows for improved control over time and ticks. (#845)
- Added a `OnNetworkDespawn` function to `NetworkObject` which gets called when a `NetworkObject` gets despawned and can be overriden. (#865)
- Added `SnapshotSystem` that would allow variables and spawn/despawn messages to be sent in blocks (#805, #852, #862, #963, #1012, #1013, #1021, #1040, #1062, #1064, #1083, #1091, #1111, #1129, #1166, #1192)
  - Disabled by default for now, except spawn/despawn messages
  - Will leverage unreliable messages with eventual consistency
- `NetworkBehaviour` and `NetworkObject`'s `NetworkManager` instances can now be overriden (#762)
- Added metrics reporting for the new network profiler if the Multiplayer Tools package is present (#1104, #1089, #1096, #1086, #1072, #1058, #960, #897, #891, #878)
- `NetworkBehaviour.IsSpawned` a quick (and stable) way to determine if the associated NetworkObject is spawned (#1190)
- Added `NetworkRigidbody` and `NetworkRigidbody2D` components to support networking `Rigidbody` and `Rigidbody2D` components (#1202, #1175)
- Added `NetworkObjectReference` and `NetworkBehaviourReference` structs which allow to sending `NetworkObject/Behaviours` over RPCs/`NetworkVariable`s (#1173)
- Added `NetworkAnimator` component to support networking `Animator` component (#1281, #872)

### Changed

- Bumped minimum Unity version, renamed package as "Unity Netcode for GameObjects", replaced `MLAPI` namespace and its variants with `Unity.Netcode` namespace and per asm-def variants (#1007, #1009, #1015, #1017, #1019, #1025, #1026, #1065)
  - Minimum Unity version:
    - 2019.4 → 2020.3+
  - Package rename:
    - Display name: `MLAPI Networking Library` → `Netcode for GameObjects`
    - Name: `com.unity.multiplayer.mlapi` → `com.unity.netcode.gameobjects`
    - Updated package description
  - All `MLAPI.x` namespaces are replaced with `Unity.Netcode`
    - `MLAPI.Messaging` → `Unity.Netcode`
    - `MLAPI.Connection` → `Unity.Netcode`
    - `MLAPI.Logging` → `Unity.Netcode`
    - `MLAPI.SceneManagement` → `Unity.Netcode`
    - and other `MLAPI.x` variants to `Unity.Netcode`
  - All assembly definitions are renamed with `Unity.Netcode.x` variants
    - `Unity.Multiplayer.MLAPI.Runtime` → `Unity.Netcode.Runtime`
    - `Unity.Multiplayer.MLAPI.Editor` → `Unity.Netcode.Editor`
    - and other `Unity.Multiplayer.MLAPI.x` variants to `Unity.Netcode.x` variants
- Renamed `Prototyping` namespace and assembly definition to `Components` (#1145)
- Changed `NetworkObject.Despawn(bool destroy)` API to default to `destroy = true` for better usability (#1217)
- Scene registration in `NetworkManager` is now replaced by Build Setttings → Scenes in Build List (#1080)
- `NetworkSceneManager.SwitchScene` has been replaced by `NetworkSceneManager.LoadScene` (#955)
- `NetworkManager, NetworkConfig, and NetworkSceneManager` scene registration replaced with scenes in build list (#1080)
- `GlobalObjectIdHash` replaced `PrefabHash` and `PrefabHashGenerator` for stability and consistency (#698)
- `NetworkStart` has been renamed to `OnNetworkSpawn`. (#865)
- Network variable cleanup - eliminated shared mode, variables are server-authoritative (#1059, #1074)
- `NetworkManager` and other systems are no longer singletons/statics (#696, #705, #706, #737, #738, #739, #746, #747, #763, #765, #766, #783, #784, #785, #786, #787, #788)
- Changed `INetworkSerializable.NetworkSerialize` method signature to use `BufferSerializer<T>` instead of `NetworkSerializer` (#1187)
- Changed `CustomMessagingManager`'s methods to use `FastBufferWriter` and `FastBufferReader` instead of `Stream` (#1187)
- Reduced internal runtime allocations by removing LINQ calls and replacing managed lists/arrays with native collections (#1196)

### Removed

- Removed `NetworkNavMeshAgent` (#1150)
- Removed `NetworkDictionary`, `NetworkSet` (#1149)
- Removed `NetworkVariableSettings` (#1097)
- Removed predefined `NetworkVariable<T>` types (#1093)
    - Removed `NetworkVariableBool`, `NetworkVariableByte`, `NetworkVariableSByte`, `NetworkVariableUShort`, `NetworkVariableShort`, `NetworkVariableUInt`, `NetworkVariableInt`, `NetworkVariableULong`, `NetworkVariableLong`, `NetworkVariableFloat`, `NetworkVariableDouble`, `NetworkVariableVector2`, `NetworkVariableVector3`, `NetworkVariableVector4`, `NetworkVariableColor`, `NetworkVariableColor32`, `NetworkVariableRay`, `NetworkVariableQuaternion`
- Removed `NetworkChannel` and `MultiplexTransportAdapter` (#1133)
- Removed ILPP backend for 2019.4, minimum required version is 2020.3+ (#895)
- `NetworkManager.NetworkConfig` had the following properties removed: (#1080)
  - Scene Registrations no longer exists
  - Allow Runtime Scene Changes was no longer needed and was removed
- Removed the NetworkObject.Spawn payload parameter (#1005)
- Removed `ProfilerCounter`, the original MLAPI network profiler, and the built-in network profiler module (2020.3). A replacement can now be found in the Multiplayer Tools package. (#1048)
- Removed UNet RelayTransport and related relay functionality in UNetTransport (#1081)
- Removed `UpdateStage` parameter from `ServerRpcSendParams` and `ClientRpcSendParams` (#1187)
- Removed `NetworkBuffer`, `NetworkWriter`, `NetworkReader`, `NetworkSerializer`, `PooledNetworkBuffer`, `PooledNetworkWriter`, and `PooledNetworkReader` (#1187)
- Removed `EnableNetworkVariable` in `NetworkConfig`, it is always enabled now (#1179)
- Removed `NetworkTransform`'s FixedSendsPerSecond, AssumeSyncedSends, InterpolateServer, ExtrapolatePosition, MaxSendsToExtrapolate, Channel, EnableNonProvokedResendChecks, DistanceSendrate (#1060) (#826) (#1042, #1055, #1061, #1084, #1101)
- Removed `NetworkManager`'s `StopServer()`, `StopClient()` and `StopHost()` methods and replaced with single `NetworkManager.Shutdown()` method for all (#1108)

### Fixed

- Fixed ServerRpc ownership check to `Debug.LogError` instead of `Debug.LogWarning` (#1126)
- Fixed `NetworkObject.OwnerClientId` property changing before `NetworkBehaviour.OnGainedOwnership()` callback (#1092)
- Fixed `NetworkBehaviourILPP` to iterate over all types in an assembly (#803)
- Fixed cross-asmdef RPC ILPP by importing types into external assemblies (#678)
- Fixed `NetworkManager` shutdown when quitting the application or switching scenes (#1011)
  - Now `NetworkManager` shutdowns correctly and despawns existing `NetworkObject`s
- Fixed Only one `PlayerPrefab` can be selected on `NetworkManager` inspector UI in the editor (#676)
- Fixed connection approval not being triggered for host (#675)
- Fixed various situations where messages could be processed in an invalid order, resulting in errors (#948, #1187, #1218)
- Fixed `NetworkVariable`s being default-initialized on the client instead of being initialized with the desired value (#1266)
- Improved runtime performance and reduced GC pressure (#1187)
- Fixed #915 - clients are receiving data from objects not visible to them (#1099)
- Fixed `NetworkTransform`'s "late join" issues, `NetworkTransform` now uses `NetworkVariable`s instead of RPCs (#826)
- Throw an exception for silent failure when a client tries to get another player's `PlayerObject`, it is now only allowed on the server-side (#844)

### Known Issues

- `NetworkVariable` does not serialize `INetworkSerializable` types through their `NetworkSerialize` implementation
- `NetworkObjects` marked as `DontDestroyOnLoad` are disabled during some network scene transitions
- `NetworkTransform` interpolates from the origin when switching Local Space synchronization
- Exceptions thrown in `OnNetworkSpawn` user code for an object will prevent the callback in other objects
- Cannot send an array of `INetworkSerializable` in RPCs
- ILPP generation fails with special characters in project path

## [0.2.0] - 2021-06-03

WIP version increment to pass package validation checks. Changelog & final version number TBD.

## [0.1.1] - 2021-06-01

This is hotfix v0.1.1 for the initial experimental Unity MLAPI Package.

### Changed

- Fixed issue with the Unity Registry package version missing some fixes from the v0.1.0 release.

## [0.1.0] - 2021-03-23

This is the initial experimental Unity MLAPI Package, v0.1.0.

### Added

- Refactored a new standard for Remote Procedure Call (RPC) in MLAPI which provides increased performance, significantly reduced boilerplate code, and extensibility for future-proofed code. MLAPI RPC includes `ServerRpc` and `ClientRpc` to execute logic on the server and client-side. This provides a single performant unified RPC solution, replacing MLAPI Convenience and Performance RPC (see [here](#removed-features)).
- Added standarized serialization types, including built-in and custom serialization flows. See [RFC #2](https://github.com/Unity-Technologies/com.unity.multiplayer.rfcs/blob/master/text/0002-serializable-types.md) for details.
- `INetworkSerializable` interface replaces `IBitWritable`.
- Added `NetworkSerializer`..., which is the main aggregator that implements serialization code for built-in supported types and holds `NetworkReader` and `NetworkWriter` instances internally.
- Added a Network Update Loop infrastructure that aids Netcode systems to update (such as RPC queue and transport) outside of the standard `MonoBehaviour` event cycle. See [RFC #8](https://github.com/Unity-Technologies/com.unity.multiplayer.rfcs/blob/master/text/0008-network-update-loop.md) and the following details:
  - It uses Unity's [low-level Player Loop API](https://docs.unity3d.com/ScriptReference/LowLevel.PlayerLoop.html) and allows for registering `INetworkUpdateSystem`s with `NetworkUpdate` methods to be executed at specific `NetworkUpdateStage`s, which may also be before or after `MonoBehaviour`-driven game logic execution.
  - You will typically interact with `NetworkUpdateLoop` for registration and `INetworkUpdateSystem` for implementation.
  - `NetworkVariable`s are now tick-based using the `NetworkTickSystem`, tracking time through network interactions and syncs.
- Added message batching to handle consecutive RPC requests sent to the same client. `RpcBatcher` sends batches based on requests from the `RpcQueueProcessing`, by batch size threshold or immediately.
- [GitHub 494](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/494): Added a constraint to allow one `NetworkObject` per `GameObject`, set through the `DisallowMultipleComponent` attribute.
- Integrated MLAPI with the Unity Profiler for versions 2020.2 and later:
  - Added new profiler modules for MLAPI that report important network data.
  - Attached the profiler to a remote player to view network data over the wire.
- A test project is available for building and experimenting with MLAPI features. This project is available in the MLAPI GitHub [testproject folder](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/tree/release/0.1.0/testproject).
- Added a [MLAPI Community Contributions](https://github.com/Unity-Technologies/mlapi-community-contributions/tree/master/com.mlapi.contrib.extensions) new GitHub repository to accept extensions from the MLAPI community. Current extensions include moved MLAPI features for lag compensation (useful for Server Authoritative actions) and `TrackedObject`.

### Changed

- [GitHub 520](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/520): MLAPI now uses the Unity Package Manager for installation management.
- Added functionality and usability to `NetworkVariable`, previously called `NetworkVar`. Updates enhance options and fully replace the need for `SyncedVar`s.
- [GitHub 507](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/507): Reimplemented `NetworkAnimator`, which synchronizes animation states for networked objects.
- GitHub [444](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/444) and [455](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/455): Channels are now represented as bytes instead of strings.

For users of previous versions of MLAPI, this release renames APIs due to refactoring. All obsolete marked APIs have been removed as per [GitHub 513](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/513) and [GitHub 514](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/514).

| Previous MLAPI Versions | V 0.1.0 Name |
| -- | -- |
| `NetworkingManager` | `NetworkManager` |
| `NetworkedObject` | `NetworkObject` |
| `NetworkedBehaviour` | `NetworkBehaviour` |
| `NetworkedClient` | `NetworkClient` |
| `NetworkedPrefab` | `NetworkPrefab` |
| `NetworkedVar` | `NetworkVariable` |
| `NetworkedTransform` | `NetworkTransform` |
| `NetworkedAnimator` | `NetworkAnimator` |
| `NetworkedAnimatorEditor` | `NetworkAnimatorEditor` |
| `NetworkedNavMeshAgent` | `NetworkNavMeshAgent` |
| `SpawnManager` | `NetworkSpawnManager` |
| `BitStream` | `NetworkBuffer` |
| `BitReader` | `NetworkReader` |
| `BitWriter` | `NetworkWriter` |
| `NetEventType` | `NetworkEventType` |
| `ChannelType` | `NetworkDelivery` |
| `Channel` | `NetworkChannel` |
| `Transport` | `NetworkTransport` |
| `NetworkedDictionary` | `NetworkDictionary` |
| `NetworkedList` | `NetworkList` |
| `NetworkedSet` | `NetworkSet` |
| `MLAPIConstants` | `NetworkConstants` |
| `UnetTransport` | `UNetTransport` |

### Fixed

- [GitHub 460](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/460): Fixed an issue for RPC where the host-server was not receiving RPCs from the host-client and vice versa without the loopback flag set in `NetworkingManager`.
- Fixed an issue where data in the Profiler was incorrectly aggregated and drawn, which caused the profiler data to increment indefinitely instead of resetting each frame.
- Fixed an issue the client soft-synced causing PlayMode client-only scene transition issues, caused when running the client in the editor and the host as a release build. Users may have encountered a soft sync of `NetworkedInstanceId` issues in the `SpawnManager.ClientCollectSoftSyncSceneObjectSweep` method.
- [GitHub 458](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/458): Fixed serialization issues in `NetworkList` and `NetworkDictionary` when running in Server mode.
- [GitHub 498](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/498): Fixed numerical precision issues to prevent not a number (NaN) quaternions.
- [GitHub 438](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/438): Fixed booleans by reaching or writing bytes instead of bits.
- [GitHub 519](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/519): Fixed an issue where calling `Shutdown()` before making `NetworkManager.Singleton = null` is null on `NetworkManager.OnDestroy()`.

### Removed

With a new release of MLAPI in Unity, some features have been removed:

- SyncVars have been removed from MLAPI. Use `NetworkVariable`s in place of this functionality. <!-- MTT54 -->
- [GitHub 527](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/527): Lag compensation systems and `TrackedObject` have moved to the new [MLAPI Community Contributions](https://github.com/Unity-Technologies/mlapi-community-contributions/tree/master/com.mlapi.contrib.extensions) repo.
- [GitHub 509](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/509): Encryption has been removed from MLAPI. The `Encryption` option in `NetworkConfig` on the `NetworkingManager` is not available in this release. This change will not block game creation or running. A current replacement for this functionality is not available, and may be developed in future releases. See the following changes:
    - Removed `SecuritySendFlags` from all APIs.
    - Removed encryption, cryptography, and certificate configurations from APIs including `NetworkManager` and `NetworkConfig`.
    - Removed "hail handshake", including `NetworkManager` implementation and `NetworkConstants` entries.
    - Modified `RpcQueue` and `RpcBatcher` internals to remove encryption and authentication from reading and writing.
- Removed the previous MLAPI Profiler editor window from Unity versions 2020.2 and later.
- Removed previous MLAPI Convenience and Performance RPC APIs with the new standard RPC API. See [RFC #1](https://github.com/Unity-Technologies/com.unity.multiplayer.rfcs/blob/master/text/0001-std-rpc-api.md) for details.
- [GitHub 520](https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi/pull/520): Removed the MLAPI Installer.

### Known Issues

- `NetworkNavMeshAgent` does not synchronize mesh data, Agent Size, Steering, Obstacle Avoidance, or Path Finding settings. It only synchronizes the destination and velocity, not the path to the destination.
- For `RPC`, methods with a `ClientRpc` or `ServerRpc` suffix which are not marked with [ServerRpc] or [ClientRpc] will cause a compiler error.
- For `NetworkAnimator`, Animator Overrides are not supported. Triggers do not work.
- For `NetworkVariable`, the `NetworkDictionary` `List` and `Set` must use the `reliableSequenced` channel.
- `NetworkObjects`s are supported but when spawning a prefab with nested child network objects you have to manually call spawn on them
- `NetworkTransform` have the following issues:
  - Replicated objects may have jitter.
  - The owner is always authoritative about the object's position.
  - Scale is not synchronized.
- Connection Approval is not called on the host client.
- For `NamedMessages`, always use `NetworkBuffer` as the underlying stream for sending named and unnamed messages.
- For `NetworkManager`, connection management is limited. Use `IsServer`, `IsClient`, `IsConnectedClient`, or other code to check if MLAPI connected correctly.

## [0.0.1-preview.1] - 2020-12-20

This was an internally-only-used version of the Unity MLAPI Package
This commit is contained in:
Unity Technologies
2020-12-20 00:00:00 +00:00
commit 22d877d1b2
489 changed files with 43246 additions and 0 deletions

View File

@@ -0,0 +1,107 @@
using System;
using Unity.Profiling;
namespace Unity.Netcode
{
public class NetworkTickSystem
{
#if DEVELOPMENT_BUILD || UNITY_EDITOR
private static ProfilerMarker s_Tick = new ProfilerMarker($"{nameof(NetworkTickSystem)}.Tick");
#endif
/// <summary>
/// Special value to indicate "No tick information"
/// </summary>
public const int NoTick = int.MinValue;
/// <summary>
/// The TickRate of the tick system. This is used to decide how often a fixed network tick is run.
/// </summary>
public uint TickRate { get; internal set; }
/// <summary>
/// The current local time. This is the time at which predicted or client authoritative objects move.
/// This value is accurate when called in Update or during the <see cref="Tick"/> event but does not work correctly for FixedUpdate.
/// </summary>
public NetworkTime LocalTime { get; internal set; }
/// <summary>
/// The current server time. This value is mostly used for internal purposes and to interpolate state received from the server.
/// This value is accurate when called in Update or during the <see cref="Tick"/> event but does not work correctly for FixedUpdate.
/// </summary>
public NetworkTime ServerTime { get; internal set; }
/// <summary>
/// Gets invoked before every network tick.
/// </summary>
public event Action Tick;
/// <summary>
/// Creates a new instance of the <see cref="NetworkTickSystem"/> class.
/// </summary>
/// <param name="tickRate">The tick rate</param>
/// <param name="localTimeSec">The initial local time to start at.</param>
/// <param name="serverTimeSec">The initial server time to start at.</param>
public NetworkTickSystem(uint tickRate, double localTimeSec, double serverTimeSec)
{
if (tickRate == 0)
{
throw new ArgumentException("Tickrate must be a positive value.", nameof(tickRate));
}
TickRate = tickRate;
Tick = null;
LocalTime = new NetworkTime(tickRate, localTimeSec);
ServerTime = new NetworkTime(tickRate, serverTimeSec);
}
/// <summary>
/// Resets the tick system to the given network time.
/// </summary>
/// <param name="localTimeSec">The local time in seconds.</param>
/// <param name="serverTimeSec">The server time in seconds.</param>
public void Reset(double localTimeSec, double serverTimeSec)
{
LocalTime = new NetworkTime(TickRate, localTimeSec);
ServerTime = new NetworkTime(TickRate, serverTimeSec);
}
/// <summary>
/// Called after advancing the time system to run ticks based on the difference in time.
/// </summary>
public void UpdateTick(double localTimeSec, double serverTimeSec)
{
// store old local tick to know how many fixed ticks passed
var previousLocalTick = LocalTime.Tick;
LocalTime = new NetworkTime(TickRate, localTimeSec);
ServerTime = new NetworkTime(TickRate, serverTimeSec);
// cache times here so that we can adjust them to temporary values while simulating ticks.
var cacheLocalTime = LocalTime;
var cacheServerTime = ServerTime;
var currentLocalTick = LocalTime.Tick;
var localToServerDifference = currentLocalTick - ServerTime.Tick;
for (int i = previousLocalTick + 1; i <= currentLocalTick; i++)
{
// set exposed time values to correct fixed values
LocalTime = new NetworkTime(TickRate, i);
ServerTime = new NetworkTime(TickRate, i - localToServerDifference);
#if DEVELOPMENT_BUILD || UNITY_EDITOR
s_Tick.Begin();
#endif
Tick?.Invoke();
#if DEVELOPMENT_BUILD || UNITY_EDITOR
s_Tick.End();
#endif
}
// Set exposed time to values from tick system
LocalTime = cacheLocalTime;
ServerTime = cacheServerTime;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8f2654d93ced8d14093426a6fea32c32
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,149 @@
using System;
using UnityEngine;
using UnityEngine.Assertions;
namespace Unity.Netcode
{
/// <summary>
/// A struct to represent a point of time in a networked game.
/// Time is stored as a combination of amount of passed ticks + a duration offset.
/// This struct is meant to replace the Unity <see cref="Time"/> API for multiplayer gameplay.
/// </summary>
public struct NetworkTime
{
private double m_TimeSec;
private uint m_TickRate;
private double m_TickInterval;
private int m_CachedTick;
private double m_CachedTickOffset;
/// <summary>
/// Gets the amount of time which has passed since the last network tick.
/// </summary>
public double TickOffset => m_CachedTickOffset;
/// <summary>
/// Gets the current time. This is a non fixed time value and similar to <see cref="Time.time"/>
/// </summary>
public double Time => m_TimeSec;
/// <summary>
/// Gets the current time as a float.
/// </summary>
public float TimeAsFloat => (float)m_TimeSec;
/// <summary>
/// Gets he current fixed network time. This is the time value of the last network tick. Similar to <see cref="Time.fixedTime"/>
/// </summary>
public double FixedTime => m_CachedTick * m_TickInterval;
/// <summary>
/// Gets the fixed delta time. This value is based on the <see cref="TickRate"/> and stays constant.
/// Similar to <see cref="Time.fixedDeltaTime"/> There is no equivalent to <see cref="Time.deltaTime"/>
/// </summary>
public float FixedDeltaTime => (float)m_TickInterval;
/// <summary>
/// Gets the amount of network ticks which have passed until reaching the current time value.
/// </summary>
public int Tick => m_CachedTick;
/// <summary>
/// Gets the tickrate of the system of this <see cref="NetworkTime"/>.
/// Ticks per second.
/// </summary>
public uint TickRate => m_TickRate;
/// <summary>
/// Creates a new instance of the <see cref="NetworkTime"/> struct.
/// </summary>
/// <param name="tickRate">The tickrate.</param>
public NetworkTime(uint tickRate)
{
Assert.IsTrue(tickRate > 0, "Tickrate must be a positive value.");
m_TickRate = tickRate;
m_TickInterval = 1f / m_TickRate; // potential floating point precision issue, could result in different interval on different machines
m_CachedTickOffset = 0;
m_CachedTick = 0;
m_TimeSec = 0;
}
/// <summary>
/// Creates a new instance of the <see cref="NetworkTime"/> struct.
/// </summary>
/// <param name="tickRate">The tickrate.</param>
/// <param name="tick">The time will be created with a value where this many tick have already passed.</param>
/// <param name="tickOffset">Can be used to create a <see cref="NetworkTime"/> with a non fixed time value by adding an offset to the given tick value.</param>
public NetworkTime(uint tickRate, int tick, double tickOffset = 0d)
: this(tickRate)
{
Assert.IsTrue(tickOffset < 1d / tickRate);
this += tick * m_TickInterval + tickOffset;
}
/// <summary>
/// Creates a new instance of the <see cref="NetworkTime"/> struct.
/// </summary>
/// <param name="tickRate">The tickrate.</param>
/// <param name="timeSec">The time value as a float.</param>
public NetworkTime(uint tickRate, double timeSec)
: this(tickRate)
{
this += timeSec;
}
/// <summary>
/// Converts the network time into a fixed time value.
/// </summary>
/// <returns>A <see cref="NetworkTime"/> where Time is the FixedTime value of this instance.</returns>
public NetworkTime ToFixedTime()
{
return new NetworkTime(m_TickRate, m_CachedTick);
}
public NetworkTime TimeTicksAgo(int ticks)
{
return this - new NetworkTime(TickRate, ticks);
}
private void UpdateCache()
{
double d = m_TimeSec / m_TickInterval;
m_CachedTick = (int)d;
m_CachedTickOffset = ((d - Math.Truncate(d)) * m_TickInterval);
// This handles negative time, decreases tick by 1 and makes offset positive.
if (m_CachedTick < 0 && m_CachedTickOffset != 0d)
{
m_CachedTick--;
m_CachedTickOffset = m_TickInterval + m_CachedTickOffset;
}
}
public static NetworkTime operator -(NetworkTime a, NetworkTime b)
{
return new NetworkTime(a.TickRate, a.Time - b.Time);
}
public static NetworkTime operator +(NetworkTime a, NetworkTime b)
{
return new NetworkTime(a.TickRate, a.Time + b.Time);
}
public static NetworkTime operator +(NetworkTime a, double b)
{
a.m_TimeSec += b;
a.UpdateCache();
return a;
}
public static NetworkTime operator -(NetworkTime a, double b)
{
return a + -b;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 675ab548d27069b4c97d61781ec01231
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,118 @@
using System;
namespace Unity.Netcode
{
/// <summary>
/// <see cref="NetworkTimeSystem"/> is a standalone system which can be used to run a network time simulation.
/// The network time system maintains both a local and a server time. The local time is based on
/// </summary>
public class NetworkTimeSystem
{
private double m_TimeSec;
private double m_CurrentLocalTimeOffset;
private double m_DesiredLocalTimeOffset;
private double m_CurrentServerTimeOffset;
private double m_DesiredServerTimeOffset;
/// <summary>
/// Gets or sets the amount of time in seconds the server should buffer incoming client messages.
/// This increases the difference between local and server time so that messages arrive earlier on the server.
/// </summary>
public double LocalBufferSec { get; set; }
/// <summary>
/// Gets or sets the amount of the time in seconds the client should buffer incoming messages from the server. This increases server time.
/// A higher value increases latency but makes the game look more smooth in bad networking conditions.
/// This value must be higher than the tick length client side.
/// </summary>
public double ServerBufferSec { get; set; }
/// <summary>
/// Gets or sets a threshold in seconds used to force a hard catchup of network time.
/// </summary>
public double HardResetThresholdSec { get; set; }
/// <summary>
/// Gets or sets the ratio at which the NetworkTimeSystem speeds up or slows down time.
/// </summary>
public double AdjustmentRatio { get; set; }
public double LocalTime => m_TimeSec + m_CurrentLocalTimeOffset;
public double ServerTime => m_TimeSec + m_CurrentServerTimeOffset;
internal double LastSyncedServerTimeSec { get; private set; }
internal double LastSyncedRttSec { get; private set; }
public NetworkTimeSystem(double localBufferSec, double serverBufferSec, double hardResetThresholdSec, double adjustmentRatio = 0.01d)
{
LocalBufferSec = localBufferSec;
ServerBufferSec = serverBufferSec;
HardResetThresholdSec = hardResetThresholdSec;
AdjustmentRatio = adjustmentRatio;
}
/// <summary>
/// Creates a new instance of the <see cref="NetworkTimeSystem"/> class for a server instance.
/// The server will not apply any buffer values which ensures that local time equals server time.
/// </summary>
/// <returns>The instance.</returns>
public static NetworkTimeSystem ServerTimeSystem()
{
return new NetworkTimeSystem(0, 0, double.MaxValue);
}
/// <summary>
/// Advances the time system by a certain amount of time. Should be called once per frame with Time.deltaTime or similar.
/// </summary>
/// <param name="deltaTimeSec">The amount of time to advance. The delta time which passed since Advance was last called.</param>
/// <returns></returns>
public bool Advance(double deltaTimeSec)
{
m_TimeSec += deltaTimeSec;
if (Math.Abs(m_DesiredLocalTimeOffset - m_CurrentLocalTimeOffset) > HardResetThresholdSec || Math.Abs(m_DesiredServerTimeOffset - m_CurrentServerTimeOffset) > HardResetThresholdSec)
{
m_TimeSec += m_DesiredServerTimeOffset;
m_DesiredLocalTimeOffset -= m_DesiredServerTimeOffset;
m_CurrentLocalTimeOffset = m_DesiredLocalTimeOffset;
m_DesiredServerTimeOffset = 0;
m_CurrentServerTimeOffset = 0;
return true;
}
m_CurrentLocalTimeOffset += deltaTimeSec * (m_DesiredLocalTimeOffset > m_CurrentLocalTimeOffset ? AdjustmentRatio : -AdjustmentRatio);
m_CurrentServerTimeOffset += deltaTimeSec * (m_DesiredServerTimeOffset > m_CurrentServerTimeOffset ? AdjustmentRatio : -AdjustmentRatio);
return false;
}
/// <summary>
/// Resets the time system to a time based on the given network parameters.
/// </summary>
/// <param name="serverTimeSec">The most recent server time value received in seconds.</param>
/// <param name="rttSec">The current RTT in seconds. Can be an averaged or a raw value.</param>
public void Reset(double serverTimeSec, double rttSec)
{
Sync(serverTimeSec, rttSec);
Advance(0);
}
/// <summary>
/// Synchronizes the time system with up-to-date network statistics but does not change any time values or advance the time.
/// </summary>
/// <param name="serverTimeSec">The most recent server time value received in seconds.</param>
/// <param name="rttSec">The current RTT in seconds. Can be an averaged or a raw value.</param>
public void Sync(double serverTimeSec, double rttSec)
{
LastSyncedRttSec = rttSec;
LastSyncedServerTimeSec = serverTimeSec;
var timeDif = serverTimeSec - m_TimeSec;
m_DesiredServerTimeOffset = timeDif - ServerBufferSec;
m_DesiredLocalTimeOffset = timeDif + rttSec + LocalBufferSec;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d802d09776f224e44af7dc71f09779d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: