Skip to content
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
84 changes: 84 additions & 0 deletions com.unity.multiplayer.mlapi/Runtime/Core/NetworkTickSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System;
using UnityEngine;

namespace MLAPI
{
// todo: This is a pretty minimal tick system. It will be improved in the future
// It currently relies on Time.unscaledTime and, as such, will start suffering
// numerical precision issues after 2^23 ticks have passed (float have 23 bits mantissa)
// For future releases, we'll need to improve on this, probably by leveraging FixedUpdate

public class NetworkTickSystem : INetworkUpdateSystem, IDisposable
{
private const float k_DefaultTickIntervalSec = 1/60f; // Defaults to 60 ticks second
private float m_TickIntervalSec; // Duration of a tick in seconds
private int m_NetworkTickCount; // How many network ticks have passed?

private static NetworkTickSystem m_Instance = null;

// special value to indicate "No tick information"
public const ushort k_NoTick = ushort.MaxValue;
// Number of ticks over which the tick number wraps back to 0
public const ushort k_TickPeriod = k_NoTick - 1;

/// <summary>
/// Constructor
/// Defaults to k_DefaultTickIntervalSec if no tick duration is specified
/// </summary>
/// <param name="tickIntervalSec">Duration of a network tick</param>
public NetworkTickSystem(float tickIntervalSec = k_DefaultTickIntervalSec)
{
this.RegisterNetworkUpdate(NetworkUpdateStage.EarlyUpdate);

//Assure we don't specify a value less than or equal to zero for tick frequency
m_TickIntervalSec = (tickIntervalSec <= 0f) ? k_DefaultTickIntervalSec : tickIntervalSec;

// ticks might not start at 0, so let's update right away at construction
UpdateNetworkTick();
}

public void Dispose()
{
this.UnregisterNetworkUpdate(NetworkUpdateStage.EarlyUpdate);
}

/// <summary>
/// GetTick
/// Gets the current network tick (non-fractional, wrapping around)
/// </summary>
/// <returns></returns>
public ushort GetTick()
{
return (ushort)(m_NetworkTickCount % k_TickPeriod);
}

/// <summary>
/// GetNetworkTime
/// Network time is calculated from m_NetworkTickCount and m_TickIntervalSec (tick frequency)
/// </summary>
/// <returns>Network Time</returns>
public float GetNetworkTime()
{
return m_NetworkTickCount * m_TickIntervalSec;
}

/// <summary>
/// UpdateNetworkTick
/// Called each network loop update during the PreUpdate stage
/// </summary>
private void UpdateNetworkTick()
{
m_NetworkTickCount = (int)(Time.unscaledTime / m_TickIntervalSec);
}

public void NetworkUpdate(NetworkUpdateStage updateStage)
{
switch (updateStage)
{
case NetworkUpdateStage.EarlyUpdate:
UpdateNetworkTick();
break;
}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions com.unity.multiplayer.mlapi/Runtime/Core/NetworkingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public class NetworkingManager : MonoBehaviour, INetworkUpdateSystem
static ProfilerMarker s_InvokeRPC = new ProfilerMarker("InvokeRPC");
#endif
internal RpcQueueContainer rpcQueueContainer { get; private set; }
internal NetworkTickSystem networkTickSystem { get; private set; }

/// <summary>
/// A synchronized time, represents the time in seconds since the server application started. Is replicated across all clients
Expand Down Expand Up @@ -383,6 +384,12 @@ private void Init(bool server)
return;
}

//This 'if' should never enter
if (networkTickSystem != null)
{
networkTickSystem.Dispose();
}
networkTickSystem = new NetworkTickSystem();

//This should never happen, but in the event that it does there should be (at a minimum) a unity error logged.
if(rpcQueueContainer != null)
Expand Down Expand Up @@ -698,6 +705,12 @@ public void Shutdown()
rpcQueueContainer = null;
}

if (networkTickSystem != null)
{
networkTickSystem.Dispose();
}
networkTickSystem = null;

NetworkProfiler.Stop();
IsListening = false;
IsServer = false;
Expand Down