Compare commits

...

13 Commits

Author SHA1 Message Date
MrGadget
3b75567d78
Merge 83fd6cbc20 into 03357f4275 2024-10-29 15:42:47 +07:00
MrGadget
83fd6cbc20 Merged master 2024-04-13 19:00:49 -04:00
MrGadget
7821e24789 Merged master 2024-01-29 02:14:35 -05:00
MrGadget
ceaa63dad1 Merged master 2024-01-22 06:27:52 -05:00
MrGadget
c719049888 Disable log 2024-01-17 04:50:47 -05:00
MrGadget
dd4f345cb6 Better naming 2024-01-17 04:50:06 -05:00
MrGadget
60a186c5f2 Comments 2024-01-17 04:38:24 -05:00
MrGadget
035afd140e Better naming 2024-01-15 18:39:31 -05:00
MrGadget
8df429d474 NetworkInformationPreview: fixed styles 2024-01-15 17:14:15 -05:00
MrGadget
8de9789faa Renamed netIdPool to netIdQueue 2024-01-15 17:01:52 -05:00
MrGadget
387be93703 Renamed poolNetworkIds to reuseNetworkIds
- Also changed header and range upper limit
2024-01-13 16:22:07 -05:00
MrGadget
3436df7ca4 Can't use TryPeek in older Unity 2024-01-12 12:24:45 -05:00
MrGadget
668dc91ffb feat(NetworkIdentity): Reuse Network IDs
- Uses a Queue (FIFO) with delay time in seconds
- Configurable in Network Manager (Enabled & Delay)
- Pool shown in NI Info Panel
2024-01-12 11:37:14 -05:00
3 changed files with 80 additions and 3 deletions

View File

@ -269,17 +269,52 @@ internal static void ResetClientStatics()
internal static void ResetServerStatics() internal static void ResetServerStatics()
{ {
reuseNetworkIds = true;
reuseDelay = 1;
netIdQueue.Clear();
nextNetworkId = 1; nextNetworkId = 1;
} }
/// <summary>Gets the NetworkIdentity from the sceneIds dictionary with the corresponding id</summary> /// <summary>Gets the NetworkIdentity from the sceneIds dictionary with the corresponding id</summary>
public static NetworkIdentity GetSceneIdentity(ulong id) => sceneIds[id]; public static NetworkIdentity GetSceneIdentity(ulong id) => sceneIds[id];
#region Network ID Reuse
internal static bool reuseNetworkIds = true;
internal static byte reuseDelay = 1;
internal struct ReusableNetworkId
{
public uint reusableNetId;
public double timeAvailable;
}
// pool of NetworkIds that can be reused
internal static readonly Queue<ReusableNetworkId> netIdQueue = new Queue<ReusableNetworkId>();
static uint nextNetworkId = 1; static uint nextNetworkId = 1;
internal static uint GetNextNetworkId() => nextNetworkId++;
internal static uint GetNextNetworkId()
{
// Older Unity versions don't have TryPeek.
if (reuseNetworkIds && netIdQueue.Count > 0 && netIdQueue.Peek().timeAvailable < NetworkTime.time)
{
ReusableNetworkId nextNetId = netIdQueue.Dequeue();
//Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, $"[GetNextNetworkId] Reusing NetworkId {nextNetId.reusableNetId}.");
return nextNetId.reusableNetId;
}
return nextNetworkId++;
}
/// <summary>Resets nextNetworkId = 1</summary> /// <summary>Resets nextNetworkId = 1</summary>
public static void ResetNextNetworkId() => nextNetworkId = 1; public static void ResetNextNetworkId()
{
netIdQueue.Clear();
nextNetworkId = 1;
}
#endregion
/// <summary>The delegate type for the clientAuthorityCallback.</summary> /// <summary>The delegate type for the clientAuthorityCallback.</summary>
public delegate void ClientAuthorityCallback(NetworkConnectionToClient conn, NetworkIdentity identity, bool authorityState); public delegate void ClientAuthorityCallback(NetworkConnectionToClient conn, NetworkIdentity identity, bool authorityState);
@ -633,6 +668,9 @@ void OnDestroy()
NetworkServer.Destroy(gameObject); NetworkServer.Destroy(gameObject);
} }
if (isServer && reuseNetworkIds && netId > 0)
netIdQueue.Enqueue(new ReusableNetworkId { reusableNetId = netId, timeAvailable = NetworkTime.time + reuseDelay });
if (isLocalPlayer) if (isLocalPlayer)
{ {
// previously there was a bug where isLocalPlayer was // previously there was a bug where isLocalPlayer was
@ -1310,7 +1348,14 @@ internal void ResetState()
isOwned = false; isOwned = false;
NotifyAuthority(); NotifyAuthority();
if (netId > 0)
{
if (reuseNetworkIds)
netIdQueue.Enqueue(new ReusableNetworkId { reusableNetId = netId, timeAvailable = NetworkTime.time + reuseDelay });
netId = 0; netId = 0;
}
connectionToServer = null; connectionToServer = null;
connectionToClient = null; connectionToClient = null;

View File

@ -47,6 +47,13 @@ public class NetworkManager : MonoBehaviour
// [Tooltip("Client broadcasts 'sendRate' times per second. Use around 60Hz for fast paced games like Counter-Strike to minimize latency. Use around 30Hz for games like WoW to minimize computations. Use around 1-10Hz for slow paced games like EVE.")] // [Tooltip("Client broadcasts 'sendRate' times per second. Use around 60Hz for fast paced games like Counter-Strike to minimize latency. Use around 30Hz for games like WoW to minimize computations. Use around 1-10Hz for slow paced games like EVE.")]
// public int clientSendRate = 30; // 33 ms // public int clientSendRate = 30; // 33 ms
[Header("Network ID Reuse")]
[Tooltip("Reuse network IDs when objects are unspawned or destroyed?")]
public bool reuseNetworkIds = true;
[Range(1, 60)]
[Tooltip("Delay in seconds before network IDs are reused")]
public byte reuseDelay = 1;
/// <summary>Automatically switch to this scene upon going offline (on start / on disconnect / on shutdown).</summary> /// <summary>Automatically switch to this scene upon going offline (on start / on disconnect / on shutdown).</summary>
[Header("Scene Management")] [Header("Scene Management")]
[Scene] [Scene]
@ -290,6 +297,10 @@ void SetupServer()
NetworkServer.disconnectInactiveTimeout = disconnectInactiveTimeout; NetworkServer.disconnectInactiveTimeout = disconnectInactiveTimeout;
NetworkServer.exceptionsDisconnect = exceptionsDisconnect; NetworkServer.exceptionsDisconnect = exceptionsDisconnect;
// Setup reuseable network IDs
NetworkIdentity.reuseNetworkIds = reuseNetworkIds;
NetworkIdentity.reuseDelay = reuseDelay;
if (runInBackground) if (runInBackground)
Application.runInBackground = true; Application.runInBackground = true;

View File

@ -113,6 +113,8 @@ public override void OnPreviewGUI(Rect r, GUIStyle background)
Y = DrawObservers(identity, initialX, Y); Y = DrawObservers(identity, initialX, Y);
Y = DrawNetworkIDQueue(initialX, Y);
_ = DrawOwner(identity, initialX, Y); _ = DrawOwner(identity, initialX, Y);
} }
@ -193,6 +195,25 @@ float DrawObservers(NetworkIdentity identity, float initialX, float Y)
return Y; return Y;
} }
float DrawNetworkIDQueue(float initialX, float Y)
{
if (NetworkIdentity.netIdQueue.Count > 0)
{
Rect netIdRect = new Rect(initialX, Y + 10, 200, 20);
GUI.Label(netIdRect, new GUIContent("Network ID Queue"), styles.labelStyle);
netIdRect.x += 20;
netIdRect.y += netIdRect.height;
foreach (var entry in NetworkIdentity.netIdQueue)
{
GUI.Label(netIdRect, $"[{entry.reusableNetId}] {entry.timeAvailable:0.000}", styles.componentName);
netIdRect.y += netIdRect.height;
Y = netIdRect.y;
}
}
return Y;
}
float DrawOwner(NetworkIdentity identity, float initialX, float Y) float DrawOwner(NetworkIdentity identity, float initialX, float Y)
{ {
if (identity.connectionToClient != null) if (identity.connectionToClient != null)