diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs index cce0bdd989..fe193643c2 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs @@ -31,6 +31,20 @@ internal class UnifiedBootstrap : ClientServerBootstrap // creates its own bootstrap, so the worlds created for other NetworkManagers are registered again. private static readonly List k_CreatedWorlds = new List(); +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() + { + Instance = null; + OnInitialized = null; + Port = 7979; + CurrentNetworkManagerForInitialization = null; + LastCreatedWorld = null; + s_WorldCounter = 0; + k_CreatedWorlds.Clear(); + } +#endif + private static void RegisterCreatedWorlds() { for (int i = k_CreatedWorlds.Count - 1; i >= 0; i--) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs index 4fe5dec349..6f565ef903 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs @@ -1266,7 +1266,12 @@ internal void Initialize(bool server) NetworkConfig.InitializePrefabs(); if (NetworkConfig.Prefabs.HasGhostPrefabs) { - NetworkConfig.NetworkTransport = gameObject.AddComponent(); + // Reused so that restarting a session does not add another transport. + if (!TryGetComponent(out UnifiedNetcodeTransport unifiedTransport)) + { + unifiedTransport = gameObject.AddComponent(); + } + NetworkConfig.NetworkTransport = unifiedTransport; } #endif #if UNIFIED_NETCODE @@ -1400,6 +1405,7 @@ internal void InitializeNetcodeWorld() TypeManager.Initialize(); UnifiedBootstrap.CurrentNetworkManagerForInitialization = this; new UnifiedBootstrap().Initialize("Default World"); + UnifiedBootstrap.CurrentNetworkManagerForInitialization = null; if (NetcodeWorld != null && NetcodeWorld.IsCreated) { diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs index d6efb70e26..860f834571 100644 --- a/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs +++ b/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs @@ -215,6 +215,16 @@ private class ConnectionInfo private Dictionary m_Connections; + private bool RemoveConnection(int connectionId) + { + if (!m_Connections.Remove(connectionId, out ConnectionInfo connectionInfo)) + { + return false; + } + connectionInfo.SendQueue.Dispose(); + return true; + } + internal void DispatchMessage(int connectionId, in FixedBytes1280 buffer) { // The connection is removed on disconnect, which can be ahead of its last messages. @@ -223,7 +233,7 @@ internal void DispatchMessage(int connectionId, in FixedBytes1280 buffer) return; } - using var arr = FixedBytes1280.ToNativeArray(buffer); + var arr = FixedBytes1280.ToNativeArray(buffer); var reader = new DataStreamReader(arr); if (connectionInfo.ReceiveQueue == null) { @@ -233,6 +243,11 @@ internal void DispatchMessage(int connectionId, in FixedBytes1280 buffer) { connectionInfo.ReceiveQueue.PushReader(reader); } +#if ENABLE_UNITY_COLLECTIONS_CHECKS + // Disposing an Allocator.None array does not release its safety handle. The queue has copied the data. + var safety = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(arr); + CollectionHelper.DisposeSafetyHandle(ref safety); +#endif var message = connectionInfo.ReceiveQueue.PopMessage(); while (message.Count != 0) @@ -278,6 +293,7 @@ public override NetworkEvent PollEvent(out ulong clientId, out ArraySegment