diff --git a/com.unity.netcode.gameobjects/Runtime/Components/NetworkAnimator.cs b/com.unity.netcode.gameobjects/Runtime/Components/NetworkAnimator.cs index 7d82872890..3fb8166408 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/NetworkAnimator.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/NetworkAnimator.cs @@ -706,7 +706,6 @@ protected virtual bool OnIsServerAuthoritative() private int[] m_TransitionHash; private int[] m_AnimationHash; private float[] m_LayerWeights; - private static byte[] s_EmptyArray = new byte[] { }; private List m_ParametersToUpdate; private RpcParams m_RpcParams; private IGroupRpcTarget m_TargetGroup; diff --git a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs index 3ca9093b34..68eeafa790 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs @@ -1361,7 +1361,7 @@ public enum AuthorityModes /// /// When set each state update will contain a state identifier /// - internal static bool TrackStateUpdateId = false; + internal static bool TrackStateUpdateId; /// /// Enabled by default. @@ -2221,13 +2221,11 @@ private bool CheckForStateChange(ref NetworkTransformState networkState, bool is // values are applied. var hasParentNetworkObject = false; - var parentNetworkObject = (NetworkObject)null; - // If the NetworkObject belonging to this NetworkTransform instance has a parent // (i.e. this handles nested NetworkTransforms under a parent at some layer above) if (NetworkObject.transform.parent != null) { - parentNetworkObject = NetworkObject.transform.parent.GetComponent(); + var parentNetworkObject = NetworkObject.transform.parent.GetComponent(); // In-scene placed NetworkObjects parented under a GameObject with no // NetworkObject preserve their lossyScale when synchronizing. @@ -4694,7 +4692,7 @@ internal static void UpdateNetworkTick(NetworkManager networkManager) /// The default value is 1 tick (plus the tick latency). When running on a local network, reducing this to 0 is recommended.
/// /// - public static int InterpolationBufferTickOffset = 0; + public static int InterpolationBufferTickOffset; internal static float GetTickLatency(NetworkManager networkManager) { if (networkManager.IsListening) @@ -4800,6 +4798,21 @@ public NetworkTransformTickRegistration(NetworkManager networkManager) } } private static int s_TickSynchPosition; + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() + { + CurrentTick = 0; + TrackStateUpdateId = false; + AssignDefaultInterpolationType = false; + DefaultInterpolationType = default; + s_NetworkTickRegistration = new Dictionary(); + InterpolationBufferTickOffset = 0; + s_TickSynchPosition = 0; + } +#endif + private int m_NextTickSync; internal void RegisterForTickSynchronization() diff --git a/com.unity.netcode.gameobjects/Runtime/Components/QuaternionCompressor.cs b/com.unity.netcode.gameobjects/Runtime/Components/QuaternionCompressor.cs index f4d9b25dd2..3c6af11529 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/QuaternionCompressor.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/QuaternionCompressor.cs @@ -44,6 +44,10 @@ public static class QuaternionCompressor // Used to store the absolute value of the 4 quaternion elements private static Quaternion s_QuatAbsValues = Quaternion.identity; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() => s_QuatAbsValues = Quaternion.identity; +#endif /// /// Compresses a Quaternion into an unsigned integer diff --git a/com.unity.netcode.gameobjects/Runtime/Components/RigidbodyContactEventManager.cs b/com.unity.netcode.gameobjects/Runtime/Components/RigidbodyContactEventManager.cs index bf54c4d964..ac54c3b6e5 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/RigidbodyContactEventManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/RigidbodyContactEventManager.cs @@ -20,7 +20,7 @@ public struct ContactEventHandlerInfo /// public bool ProvideNonRigidBodyContactEvents; /// - /// When set to true, the will prioritize invoking

+ /// When set to true, the will prioritize invoking
/// if it is the 2nd colliding body in the contact pair being processed. With distributed authority, setting this value to true when a is owned by the local client
/// will assure is only invoked on the authoritative side. ///
@@ -76,6 +76,10 @@ public interface IContactEventHandlerWithInfo : IContactEventHandler public class RigidbodyContactEventManager : MonoBehaviour { public static RigidbodyContactEventManager Instance { get; private set; } +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() => Instance = null; +#endif private struct JobResultStruct { diff --git a/com.unity.netcode.gameobjects/Runtime/Configuration/CommandLineOptions.cs b/com.unity.netcode.gameobjects/Runtime/Configuration/CommandLineOptions.cs index c6f9b4a222..8a550b0542 100644 --- a/com.unity.netcode.gameobjects/Runtime/Configuration/CommandLineOptions.cs +++ b/com.unity.netcode.gameobjects/Runtime/Configuration/CommandLineOptions.cs @@ -30,32 +30,31 @@ private set } private static CommandLineOptions s_Instance; - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] - private static void RuntimeInitializeOnLoad() => Instance = new CommandLineOptions(); - // Contains the current application instance domain's command line arguments - internal static List CommandLineArguments = new List(); - - // Invoked upon application start, after scene load - [RuntimeInitializeOnLoadMethod] - private static void ParseCommandLineArguments() + private static List s_CommandLineArguments = new List(Environment.GetCommandLineArgs()); +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() { + Instance = new CommandLineOptions(); + s_Instance = new CommandLineOptions(); // Get all the command line arguments to be parsed later and/or modified // prior to being parsed (for testing purposes). - CommandLineArguments = new List(Environment.GetCommandLineArgs()); + s_CommandLineArguments = new List(Environment.GetCommandLineArgs()); } +#endif /// - /// Returns the value of an argument or null if there the argument is not present + /// Returns the value of an argument or null if the argument is not present /// /// The name of the argument /// Value of the command line argument passed in. public string GetArg(string arg) { - var argIndex = CommandLineArguments.IndexOf(arg); - if (argIndex >= 0 && argIndex < CommandLineArguments.Count - 1) + var argIndex = s_CommandLineArguments.IndexOf(arg); + if (argIndex >= 0 && argIndex < s_CommandLineArguments.Count - 1) { - return CommandLineArguments[argIndex + 1]; + return s_CommandLineArguments[argIndex + 1]; } return null; } diff --git a/com.unity.netcode.gameobjects/Runtime/Core/ComponentFactory.cs b/com.unity.netcode.gameobjects/Runtime/Core/ComponentFactory.cs index 52945c4e46..1616ac727b 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/ComponentFactory.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/ComponentFactory.cs @@ -1,5 +1,8 @@ using System; using System.Collections.Generic; +#if UNITY_EDITOR +using UnityEngine; +#endif namespace Unity.Netcode { @@ -14,6 +17,10 @@ internal static class ComponentFactory internal delegate object CreateObjectDelegate(NetworkManager networkManager); private static Dictionary s_Delegates = new Dictionary(); +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() => s_Delegates = new Dictionary(); +#endif /// /// Instantiates an instance of a given interface diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs index 14f8ea5dfb..00916f459d 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs @@ -1333,8 +1333,6 @@ internal void NetworkVariableUpdate(ulong targetClientId, bool forceSend = false } } - internal static bool LogSentVariableUpdateMessage; - private bool CouldHaveDirtyNetworkVariables() { // TODO: There should be a better way by reading one dirty variable vs. 'n' diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs index d8bcfaffff..b40025e90f 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs @@ -1809,6 +1809,19 @@ internal abstract class NetcodeAnalytics internal delegate void ResetNetworkManagerDelegate(NetworkManager manager); internal static ResetNetworkManagerDelegate OnNetworkManagerReset; + //We already are in an #if UNITY_ENGINE def + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() + { + Singleton = null; + OnInstantiated = null; + OnDestroying = null; + OnSingletonReady = null; + OnNetworkManagerReset = null; + IsDistributedAuthority = false; + s_SerializedType = new List(); + DisableNotOptimizedSerializedType = false; + } private void Reset() { diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs index 335fec109f..7821173220 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs @@ -1729,6 +1729,11 @@ internal void SetIsDestroying() IsDestroying = true; } + private void OnDisable() + { + SceneManager.activeSceneChanged -= CurrentlyActiveSceneChanged; + } + private void OnDestroy() { // Apply the is destroying flag @@ -2506,6 +2511,10 @@ private void OnTransformParentChanged() // If you couldn't find your parent, we put you into OrphanChildren set and every time we spawn another NetworkObject locally due to replication, // we call CheckOrphanChildren() method and quickly iterate over OrphanChildren set and see if we can reparent/adopt one. internal static HashSet OrphanChildren = new HashSet(); +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() => OrphanChildren = new HashSet(); +#endif internal bool ApplyNetworkParenting(bool removeParent = false, bool ignoreNotSpawned = false, bool orphanedChildPass = false, bool enableNotification = true) { diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkUpdateLoop.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkUpdateLoop.cs index c48dea0333..9d44394393 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkUpdateLoop.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkUpdateLoop.cs @@ -70,19 +70,19 @@ public enum NetworkUpdateStage : byte /// public static class NetworkUpdateLoop { - private static Dictionary> s_UpdateSystem_Sets; - private static Dictionary s_UpdateSystem_Arrays; - private const int k_UpdateSystem_InitialArrayCapacity = 1024; + private static Dictionary> s_UpdateSystemSets; + private static Dictionary s_UpdateSystemArrays; + private const int k_UpdateSystemInitialArrayCapacity = 1024; static NetworkUpdateLoop() { - s_UpdateSystem_Sets = new Dictionary>(); - s_UpdateSystem_Arrays = new Dictionary(); + s_UpdateSystemSets = new Dictionary>(); + s_UpdateSystemArrays = new Dictionary(); foreach (NetworkUpdateStage updateStage in Enum.GetValues(typeof(NetworkUpdateStage))) { - s_UpdateSystem_Sets.Add(updateStage, new HashSet()); - s_UpdateSystem_Arrays.Add(updateStage, new INetworkUpdateSystem[k_UpdateSystem_InitialArrayCapacity]); + s_UpdateSystemSets.Add(updateStage, new HashSet()); + s_UpdateSystemArrays.Add(updateStage, new INetworkUpdateSystem[k_UpdateSystemInitialArrayCapacity]); } } @@ -105,19 +105,19 @@ public static void RegisterAllNetworkUpdates(this INetworkUpdateSystem updateSys /// The being registered for the implementation public static void RegisterNetworkUpdate(this INetworkUpdateSystem updateSystem, NetworkUpdateStage updateStage = NetworkUpdateStage.Update) { - var sysSet = s_UpdateSystem_Sets[updateStage]; + var sysSet = s_UpdateSystemSets[updateStage]; if (!sysSet.Contains(updateSystem)) { sysSet.Add(updateSystem); int setLen = sysSet.Count; - var sysArr = s_UpdateSystem_Arrays[updateStage]; + var sysArr = s_UpdateSystemArrays[updateStage]; int arrLen = sysArr.Length; if (setLen > arrLen) { // double capacity - sysArr = s_UpdateSystem_Arrays[updateStage] = new INetworkUpdateSystem[arrLen *= 2]; + sysArr = s_UpdateSystemArrays[updateStage] = new INetworkUpdateSystem[arrLen *= 2]; } sysSet.CopyTo(sysArr); @@ -149,13 +149,13 @@ public static void UnregisterAllNetworkUpdates(this INetworkUpdateSystem updateS /// The to be deregistered from the implementation public static void UnregisterNetworkUpdate(this INetworkUpdateSystem updateSystem, NetworkUpdateStage updateStage = NetworkUpdateStage.Update) { - var sysSet = s_UpdateSystem_Sets[updateStage]; + var sysSet = s_UpdateSystemSets[updateStage]; if (sysSet.Contains(updateSystem)) { sysSet.Remove(updateSystem); int setLen = sysSet.Count; - var sysArr = s_UpdateSystem_Arrays[updateStage]; + var sysArr = s_UpdateSystemArrays[updateStage]; int arrLen = sysArr.Length; sysSet.CopyTo(sysArr); @@ -177,7 +177,7 @@ internal static void RunNetworkUpdateStage(NetworkUpdateStage updateStage) { UpdateStage = updateStage; - var sysArr = s_UpdateSystem_Arrays[updateStage]; + var sysArr = s_UpdateSystemArrays[updateStage]; int arrLen = sysArr.Length; for (int curIdx = 0; curIdx < arrLen; curIdx++) { @@ -291,6 +291,16 @@ public static PlayerLoopSystem CreateLoopSystem() [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void Initialize() { +#if UNITY_EDITOR + s_UpdateSystemSets = new Dictionary>(); + s_UpdateSystemArrays = new Dictionary(); + foreach (NetworkUpdateStage updateStage in Enum.GetValues(typeof(NetworkUpdateStage))) + { + s_UpdateSystemSets.Add(updateStage, new HashSet()); + s_UpdateSystemArrays.Add(updateStage, new INetworkUpdateSystem[k_UpdateSystemInitialArrayCapacity]); + } + UpdateStage = default; +#endif UnregisterLoopSystems(); RegisterLoopSystems(); } diff --git a/com.unity.netcode.gameobjects/Runtime/Logging/NetworkLog.cs b/com.unity.netcode.gameobjects/Runtime/Logging/NetworkLog.cs index 59557cc81a..f64f88db72 100644 --- a/com.unity.netcode.gameobjects/Runtime/Logging/NetworkLog.cs +++ b/com.unity.netcode.gameobjects/Runtime/Logging/NetworkLog.cs @@ -58,6 +58,10 @@ public static class NetworkLog public static void LogErrorServer(string message) => LogServer(message, LogType.Error); internal static NetworkManager NetworkManagerOverride; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() => NetworkManagerOverride = null; +#endif private static void LogServer(string message, LogType logType) { diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/DeferredMessageManager.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/DeferredMessageManager.cs index f05d000fec..c2bdba09c6 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/DeferredMessageManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/DeferredMessageManager.cs @@ -1,5 +1,8 @@ using System.Collections.Generic; using Unity.Collections; +#if UNITY_EDITOR +using UnityEngine; +#endif namespace Unity.Netcode { @@ -96,6 +99,10 @@ public virtual unsafe void CleanupStaleTriggers() /// Used for testing purposes ///
internal static bool IncludeMessageType = true; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() => IncludeMessageType = true; +#endif private string GetWarningMessage(IDeferredNetworkMessageManager.TriggerType triggerType, ulong key, TriggerInfo triggerInfo, float spawnTimeout) { diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs index ec460cc821..c2a973fb4b 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; #if UNITY_EDITOR +using UnityEngine; using UnityEditor; #endif @@ -53,6 +54,10 @@ internal struct ILPPMessageProvider : INetworkMessageProvider // Enable this for integration tests that need no message types defined internal static bool IntegrationTestNoMessages; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() => IntegrationTestNoMessages = false; +#endif /// /// Returns a table of message type to NetworkMessageTypes enum value diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/INetworkMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/INetworkMessage.cs index fe481d25f5..6517d63675 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/INetworkMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/INetworkMessage.cs @@ -1,4 +1,3 @@ - namespace Unity.Netcode { /// diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/MessageDelivery.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/MessageDelivery.cs index e8cf2ca6db..3a6f34b274 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/MessageDelivery.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/MessageDelivery.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using Unity.Netcode; -using UnityEditor; using UnityEngine; internal static class MessageDelivery @@ -15,17 +14,21 @@ internal static class MessageDelivery /// when sending the message via public API. /// - Skip the time sync messages since it has always used unreliable network delivery. /// - private static HashSet s_SkipMessageTypes = new HashSet(){ + private static readonly HashSet k_SkipMessageTypes = new HashSet(){ NetworkMessageTypes.NamedMessage, NetworkMessageTypes.Unnamed}; - [RuntimeInitializeOnLoadMethod] + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void OnApplicationStart() { +#if UNITY_EDITOR + s_MessageToDelivery = new Dictionary(); + s_MessageToMessageType = new Dictionary(); +#endif UpdateMessageTypes(); } /// - /// FIrst pass at providing an easier path to configuring the network + /// First pass at providing an easier path to configuring the network /// delivery type for the message type. /// TODO: Once coalesces all reliable messages /// and/or organizes by a more unified order of operation tracking built into the @@ -40,7 +43,7 @@ private static void UpdateMessageTypes() foreach (var messageTypeObject in networkMessageTypes) { var messageType = (NetworkMessageTypes)messageTypeObject; - if (s_SkipMessageTypes.Contains(messageType)) + if (k_SkipMessageTypes.Contains(messageType)) { continue; } @@ -71,18 +74,10 @@ private static void UpdateMessageTypes() MessageDeliveryType.Initialize(); } -#if UNITY_EDITOR - [InitializeOnLoadMethod] - [InitializeOnEnterPlayMode] - private static void OnEnterPlayMode() - { - UpdateMessageTypes(); - } -#endif internal static NetworkDelivery GetDelivery(Type type) { // Return the default if not registered or null - if (type == null || s_SkipMessageTypes.Contains(s_MessageToMessageType[type])) + if (type == null || k_SkipMessageTypes.Contains(s_MessageToMessageType[type])) { return NetworkDelivery.ReliableFragmentedSequenced; } @@ -91,7 +86,7 @@ internal static NetworkDelivery GetDelivery(Type type) internal static NetworkDelivery GetDelivery(NetworkMessageTypes messageType) { - if (s_SkipMessageTypes.Contains(messageType)) + if (k_SkipMessageTypes.Contains(messageType)) { throw new Exception($"{messageType} is not registered in the message type to network delivery map!"); } diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs index c66aa62273..53714455c6 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs @@ -34,9 +34,9 @@ public InvalidMessageStructureException(string issue) : base(issue) internal class NetworkMessageManager : IDisposable { public bool StopProcessing = false; - private static Type s_ConnectionApprovedType = typeof(ConnectionApprovedMessage); - private static Type s_ConnectionRequestType = typeof(ConnectionRequestMessage); - private static Type s_DisconnectReasonType = typeof(DisconnectReasonMessage); + private static readonly Type k_ConnectionApprovedType = typeof(ConnectionApprovedMessage); + private static readonly Type k_ConnectionRequestType = typeof(ConnectionRequestMessage); + private static readonly Type k_DisconnectReasonType = typeof(DisconnectReasonMessage); private struct ReceiveQueueItem { @@ -149,8 +149,6 @@ public NetworkMessageManager(INetworkMessageSender sender, object owner, INetwor } } - internal static bool EnableMessageOrderConsoleLog = false; - public void Dispose() { if (m_Disposed) @@ -549,7 +547,7 @@ internal int GetMessageVersion(Type type, ulong clientId, bool forReceive = fals // Special cases because these are the messages that carry the version info - thus the version info isn't // populated yet when we get these. The first part of these messages always has to be the version data // and can't change. - if (messageType != s_ConnectionRequestType && messageType != s_ConnectionApprovedType && messageType != s_DisconnectReasonType && context.SenderId != manager.m_LocalClientId) + if (messageType != k_ConnectionRequestType && messageType != k_ConnectionApprovedType && messageType != k_DisconnectReasonType && context.SenderId != manager.m_LocalClientId) { messageVersion = manager.GetMessageVersion(messageType, context.SenderId, true); if (messageVersion < 0) @@ -603,7 +601,7 @@ internal int SendMessage(ref TMessageType messa var messageVersion = 0; // Special case because this is the message that carries the version info - thus the version info isn't populated yet when we get this. // The first part of this message always has to be the version data and can't change. - if (typeof(TMessageType) != s_ConnectionRequestType) + if (typeof(TMessageType) != k_ConnectionRequestType) { messageVersion = GetMessageVersion(typeof(TMessageType), clientIds[i]); if (messageVersion < 0) @@ -657,7 +655,7 @@ internal unsafe int SendPreSerializedMessage(in FastBufferWriter t // Special case because this is the message that carries the version info - thus the version info isn't populated yet when we get this. // The first part of this message always has to be the version data and can't change. - if (typeof(TMessageType) != s_ConnectionRequestType) + if (typeof(TMessageType) != k_ConnectionRequestType) { var messageVersion = GetMessageVersion(typeof(TMessageType), clientIds[i]); if (messageVersion < 0) @@ -741,7 +739,7 @@ internal unsafe int SendPreSerializedMessage(in FastBufferWriter t // Special case because this is the message that carries the version info - thus the version info isn't // populated yet when we get this. The first part of this message always has to be the version data // and can't change. - if (typeof(TMessageType) != s_ConnectionRequestType) + if (typeof(TMessageType) != k_ConnectionRequestType) { messageVersion = GetMessageVersion(typeof(TMessageType), clientId); if (messageVersion < 0) diff --git a/com.unity.netcode.gameobjects/Runtime/Metrics/NetworkMetrics.cs b/com.unity.netcode.gameobjects/Runtime/Metrics/NetworkMetrics.cs index b171932103..06b15d9368 100644 --- a/com.unity.netcode.gameobjects/Runtime/Metrics/NetworkMetrics.cs +++ b/com.unity.netcode.gameobjects/Runtime/Metrics/NetworkMetrics.cs @@ -1,6 +1,9 @@ #if MULTIPLAYER_TOOLS using System; using System.Collections.Generic; +#if UNITY_EDITOR +using UnityEngine; +#endif using Unity.Multiplayer.Tools; using Unity.Multiplayer.Tools.MetricTypes; using Unity.Multiplayer.Tools.NetStats; @@ -13,6 +16,18 @@ internal class NetworkMetrics : INetworkMetrics private const ulong k_MaxMetricsPerFrame = 1000L; private static Dictionary s_SceneEventTypeNames; private static ProfilerMarker s_FrameDispatch = new ProfilerMarker($"{nameof(NetworkMetrics)}.DispatchFrame"); +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() + { + s_SceneEventTypeNames = new Dictionary(); + foreach (SceneEventType type in Enum.GetValues(typeof(SceneEventType))) + { + s_SceneEventTypeNames[(uint)type] = type.ToString(); + } + s_FrameDispatch = new ProfilerMarker($"{nameof(NetworkMetrics)}.DispatchFrame"); + } +#endif static NetworkMetrics() { diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs index 25abeb20e9..52b3359867 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs @@ -307,6 +307,10 @@ internal void UpdateLastSentTime() } internal static bool IgnoreInitializeWarning; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() => IgnoreInitializeWarning = false; +#endif /// /// Marks the associated NetworkBehaviour as dirty, indicating it needs synchronization diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Serialization/TypedILPPInitializers.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Serialization/TypedILPPInitializers.cs index 9fd42b2ae3..9671d0b66c 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Serialization/TypedILPPInitializers.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Serialization/TypedILPPInitializers.cs @@ -20,7 +20,7 @@ namespace Unity.Netcode /// public static class NetworkVariableSerializationTypedInitializers { - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] #if UNITY_EDITOR [InitializeOnLoadMethod] #endif diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs index 2fbdf1fbe9..7b7f9cae00 100644 --- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs @@ -548,6 +548,15 @@ internal bool RemoveServerClientSceneHandle(NetworkSceneHandle serverHandle, Net /// not destroy temporary scene are moved into the active scene /// internal static bool IsSpawnedObjectsPendingInDontDestroyOnLoad; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() + { + DisableReSynchronization = false; + IsSpawnedObjectsPendingInDontDestroyOnLoad = false; + SceneUnloadEventHandler.ResetInstances(); + } +#endif /// /// Client and Server: @@ -1570,6 +1579,9 @@ public SceneEventProgressStatus LoadScene(string sceneName, LoadSceneMode loadSc internal class SceneUnloadEventHandler { private static Dictionary> s_Instances = new Dictionary>(); +#if UNITY_EDITOR + internal static void ResetInstances() => s_Instances = new Dictionary>(); +#endif internal static void RegisterScene(NetworkSceneManager networkSceneManager, Scene scene, LoadSceneMode loadSceneMode, AsyncOperation asyncOperation = null) { diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs index 0fff313574..3de3eccadc 100644 --- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs +++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs @@ -3,6 +3,9 @@ using System.Linq; using System.Text; using Unity.Collections; +#if UNITY_EDITOR +using UnityEngine; +#endif using UnityEngine.SceneManagement; namespace Unity.Netcode @@ -168,7 +171,7 @@ internal class SceneEventData : IDisposable /// Look for usage to see where /// entries are being added to or removed from the table /// - /// + /// /// internal void AddSceneToSynchronize(uint sceneHash, NetworkSceneHandle sceneHandle) { @@ -316,7 +319,11 @@ private void SortParentedNetworkObjects() } } - internal static bool LogSerializationOrder = false; + internal static bool LogSerializationOrder; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() => LogSerializationOrder = false; +#endif internal void AddSpawnedNetworkObjects() { @@ -1026,8 +1033,6 @@ private void DeserializeDespawnedInScenePlacedNetworkObjects() var localSceneHandle = m_NetworkManager.SceneManager.ServerSceneHandleToClientSceneHandle[networkSceneHandle]; if (m_NetworkManager.SceneManager.ScenesLoaded.ContainsKey(localSceneHandle)) { - var objectRelativeScene = m_NetworkManager.SceneManager.ScenesLoaded[localSceneHandle]; - // Find all active and non-active in-scene placed NetworkObjects var inSceneNetworkObjects = FindObjects.ByType(true, true).Where((c) => c.GetSceneOriginHandle() == localSceneHandle && (c.IsSceneObject != false)).ToList(); diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/FastBufferWriter.cs b/com.unity.netcode.gameobjects/Runtime/Serialization/FastBufferWriter.cs index bea537965e..ca39ea8c62 100644 --- a/com.unity.netcode.gameobjects/Runtime/Serialization/FastBufferWriter.cs +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/FastBufferWriter.cs @@ -31,7 +31,7 @@ internal struct WriterHandle internal unsafe WriterHandle* Handle; - private static byte[] s_ByteArrayCache = new byte[65535]; + private static readonly byte[] k_ByteArrayCache = new byte[65535]; /// /// The current write position @@ -379,17 +379,17 @@ public unsafe byte[] ToArray() internal unsafe ArraySegment ToTempByteArray() { var length = Length; - if (length > s_ByteArrayCache.Length) + if (length > k_ByteArrayCache.Length) { return new ArraySegment(ToArray(), 0, length); } - fixed (byte* b = s_ByteArrayCache) + fixed (byte* b = k_ByteArrayCache) { UnsafeUtility.MemCpy(b, Handle->BufferPointer, length); } - return new ArraySegment(s_ByteArrayCache, 0, length); + return new ArraySegment(k_ByteArrayCache, 0, length); } /// diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs index 19cecefc48..0b2e406e4f 100644 --- a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs @@ -11,8 +11,7 @@ public struct NetworkBehaviourReference : INetworkSerializable, IEquatable /// Creates a new instance of the struct. @@ -24,7 +23,7 @@ public NetworkBehaviourReference(NetworkBehaviour networkBehaviour) if (networkBehaviour == null) { m_NetworkObjectReference = new NetworkObjectReference((NetworkObject)null); - m_NetworkBehaviourId = s_NullId; + m_NetworkBehaviourId = k_NullId; return; } if (networkBehaviour.NetworkObject == null) @@ -64,7 +63,7 @@ public bool TryGet(out T networkBehaviour, NetworkManager networkManager = nu [MethodImpl(MethodImplOptions.AggressiveInlining)] private static NetworkBehaviour GetInternal(NetworkBehaviourReference networkBehaviourRef, NetworkManager networkManager = null) { - if (networkBehaviourRef.m_NetworkBehaviourId == s_NullId) + if (networkBehaviourRef.m_NetworkBehaviourId == k_NullId) { return null; } diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs index 32ab0ed162..db5ed69ced 100644 --- a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs @@ -10,7 +10,7 @@ namespace Unity.Netcode public struct NetworkObjectReference : INetworkSerializable, IEquatable { private ulong m_NetworkObjectId; - private static ulong s_NullId = ulong.MaxValue; + private const ulong k_NullId = ulong.MaxValue; /// /// The of the referenced . @@ -31,7 +31,7 @@ public NetworkObjectReference(NetworkObject networkObject) { if (networkObject == null) { - m_NetworkObjectId = s_NullId; + m_NetworkObjectId = k_NullId; return; } @@ -53,7 +53,7 @@ public NetworkObjectReference(GameObject gameObject) { if (gameObject == null) { - m_NetworkObjectId = s_NullId; + m_NetworkObjectId = k_NullId; return; } @@ -92,7 +92,7 @@ public bool TryGet(out NetworkObject networkObject, NetworkManager networkManage [MethodImpl(MethodImplOptions.AggressiveInlining)] private static NetworkObject Resolve(NetworkObjectReference networkObjectRef, NetworkManager networkManager = null) { - if (networkObjectRef.m_NetworkObjectId == s_NullId) + if (networkObjectRef.m_NetworkObjectId == k_NullId) { return null; } diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/SinglePlayer/SinglePlayerTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/SinglePlayer/SinglePlayerTransport.cs index 7b2d6b1719..e94955618c 100644 --- a/com.unity.netcode.gameobjects/Runtime/Transports/SinglePlayer/SinglePlayerTransport.cs +++ b/com.unity.netcode.gameobjects/Runtime/Transports/SinglePlayer/SinglePlayerTransport.cs @@ -20,7 +20,7 @@ public class SinglePlayerTransport : NetworkTransport /// public override ulong ServerClientId { get; } = 0; - internal static string NotStartingAsHostErrorMessage = $"When using {nameof(SinglePlayerTransport)}, you must start a hosted session so both client and server are available locally."; + internal static readonly string NotStartingAsHostErrorMessage = $"When using {nameof(SinglePlayerTransport)}, you must start a hosted session so both client and server are available locally."; private struct MessageData { @@ -31,6 +31,10 @@ private struct MessageData } private static Dictionary> s_MessageQueue = new Dictionary>(); +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() => s_MessageQueue = new Dictionary>(); +#endif private ulong m_TransportId = 0; private NetworkManager m_NetworkManager; diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs index b39fe2bc94..1cd059fab8 100644 --- a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs +++ b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs @@ -68,7 +68,7 @@ public enum ProtocolType // frame at 60 FPS. This will be a large over-estimation in any realistic scenario. private const int k_MaxReliableThroughput = (NetworkParameterConstants.MTU * 64 * 60) / 1000; // bytes per millisecond - private static ConnectionAddressData s_DefaultConnectionAddressData = new ConnectionAddressData { Address = "127.0.0.1", Port = 7777, WebSocketPath = "/", ServerListenAddress = string.Empty }; + private static readonly ConnectionAddressData k_DefaultConnectionAddressData = new ConnectionAddressData { Address = "127.0.0.1", Port = 7777, WebSocketPath = "/", ServerListenAddress = string.Empty }; #pragma warning disable IDE1006 // Naming Styles /// @@ -308,7 +308,7 @@ public NetworkEndpoint ListenEndPoint /// This is where you can change IP Address, Port, or server's listen address. /// /// - public ConnectionAddressData ConnectionData = s_DefaultConnectionAddressData; + public ConnectionAddressData ConnectionData = k_DefaultConnectionAddressData; /// /// Parameters for the Network Simulator @@ -369,6 +369,19 @@ private struct PacketLossCache #endif internal static event Action TransportInitialized; internal static event Action TransportDisposed; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void ResetStaticsOnLoad() + { + s_DriverConstructor = null; +#if UNITY_6000_2_OR_NEWER + OnDriverInitialized = null; + OnDisposingDriver = null; +#endif + TransportInitialized = null; + TransportDisposed = null; + } +#endif /// /// Provides access to the for this instance. diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs index 1253371448..4e48d678a8 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs @@ -2400,8 +2400,6 @@ public NetcodeIntegrationTest(HostOrServer hostOrServer) private void InitializeTestConfiguration(NetworkTopologyTypes networkTopologyType, HostOrServer? hostOrServer) { - NetworkMessageManager.EnableMessageOrderConsoleLog = false; - // Set m_NetworkTopologyType first because m_DistributedAuthority is calculated from it. m_NetworkTopologyType = networkTopologyType;