This commit is contained in:
MrGadget 2024-10-29 15:42:47 +07:00 committed by GitHub
commit 3b75567d78
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 80 additions and 3 deletions

View File

@ -269,17 +269,52 @@ internal static void ResetClientStatics()
internal static void ResetServerStatics()
{
reuseNetworkIds = true;
reuseDelay = 1;
netIdQueue.Clear();
nextNetworkId = 1;
}
/// <summary>Gets the NetworkIdentity from the sceneIds dictionary with the corresponding id</summary>
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;
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>
public static void ResetNextNetworkId() => nextNetworkId = 1;
public static void ResetNextNetworkId()
{
netIdQueue.Clear();
nextNetworkId = 1;
}
#endregion
/// <summary>The delegate type for the clientAuthorityCallback.</summary>
public delegate void ClientAuthorityCallback(NetworkConnectionToClient conn, NetworkIdentity identity, bool authorityState);
@ -633,6 +668,9 @@ void OnDestroy()
NetworkServer.Destroy(gameObject);
}
if (isServer && reuseNetworkIds && netId > 0)
netIdQueue.Enqueue(new ReusableNetworkId { reusableNetId = netId, timeAvailable = NetworkTime.time + reuseDelay });
if (isLocalPlayer)
{
// previously there was a bug where isLocalPlayer was
@ -1310,7 +1348,14 @@ internal void ResetState()
isOwned = false;
NotifyAuthority();
netId = 0;
if (netId > 0)
{
if (reuseNetworkIds)
netIdQueue.Enqueue(new ReusableNetworkId { reusableNetId = netId, timeAvailable = NetworkTime.time + reuseDelay });
netId = 0;
}
connectionToServer = 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.")]
// 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>
[Header("Scene Management")]
[Scene]
@ -290,6 +297,10 @@ void SetupServer()
NetworkServer.disconnectInactiveTimeout = disconnectInactiveTimeout;
NetworkServer.exceptionsDisconnect = exceptionsDisconnect;
// Setup reuseable network IDs
NetworkIdentity.reuseNetworkIds = reuseNetworkIds;
NetworkIdentity.reuseDelay = reuseDelay;
if (runInBackground)
Application.runInBackground = true;

View File

@ -113,6 +113,8 @@ public override void OnPreviewGUI(Rect r, GUIStyle background)
Y = DrawObservers(identity, initialX, Y);
Y = DrawNetworkIDQueue(initialX, Y);
_ = DrawOwner(identity, initialX, Y);
}
@ -193,6 +195,25 @@ float DrawObservers(NetworkIdentity identity, float initialX, float 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)
{
if (identity.connectionToClient != null)