Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c6f0d4b
fix: reset static fields for Fast Enter Play Mode
noellie-velez Apr 24, 2026
702bb73
Remove RuntimeInitializeOnLoadMethod from non generic types
noellie-velez Apr 24, 2026
8dabded
Fix naming + if editor def on `using UnityEngine`
noellie-velez Apr 24, 2026
aa33ed6
Merge branch 'develop-2.0.0' into chore/fast-enter-playmode
noellie-velez Apr 24, 2026
5ab98dc
Styling, renaming and made a field readonly
noellie-velez Apr 24, 2026
69dce92
Merge branch 'develop-2.0.0' into chore/fast-enter-playmode
noellie-velez Apr 28, 2026
638855f
Fix code formatting issues (redundant UnityEngine)
noellie-velez Apr 28, 2026
4cbec9b
Merge branch 'develop-2.0.0' into chore/fast-enter-playmode
noellie-velez May 6, 2026
0ecf34c
Add AutoStaticsCleanup + fix typo
noellie-velez May 6, 2026
e65351c
Remove possible NullReferenceException
noellie-velez May 6, 2026
551b989
Unused parented children list cleanup
noellie-velez May 7, 2026
689ecd2
Merge branch 'develop-2.0.0' into chore/fast-enter-playmode
NoelStephensUnity May 8, 2026
25e456b
Merge branch 'develop-2.0.0' into chore/fast-enter-playmode
NoelStephensUnity May 12, 2026
70c90eb
Merge branch 'develop-2.0.0' into chore/fast-enter-playmode
NoelStephensUnity May 18, 2026
a889166
Review
noellie-velez May 18, 2026
9febb5e
Merge branch 'chore/fast-enter-playmode' of github.com:Unity-Technolo…
noellie-velez May 18, 2026
46e09ab
Finalize addressing review comments
noellie-velez May 18, 2026
ff2e26a
revert field removal
noellie-velez May 21, 2026
be40aa3
Readonly, missing MessageTypes, replace quat...
noellie-velez May 21, 2026
dbeccdf
Small fixes
noellie-velez May 21, 2026
f184559
Diable Domain Reload + remove warning as errors
noellie-velez May 21, 2026
99b4f18
Adding NetworkManager singleton reset test
noellie-velez May 21, 2026
935ebe1
Changelog update
noellie-velez May 21, 2026
e315369
Apply suggestion from @noellie-velez
noellie-velez May 21, 2026
2ac827f
fix indentation + naming convention
noellie-velez May 21, 2026
1575029
Fix test accesibility
noellie-velez May 21, 2026
9dc2b33
Small missed rename fix
noellie-velez May 21, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> m_ParametersToUpdate;
private RpcParams m_RpcParams;
private IGroupRpcTarget m_TargetGroup;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1361,7 +1361,7 @@ public enum AuthorityModes
/// <summary>
/// When set each state update will contain a state identifier
/// </summary>
internal static bool TrackStateUpdateId = false;
internal static bool TrackStateUpdateId;

/// <summary>
/// Enabled by default.
Expand Down Expand Up @@ -2062,19 +2062,6 @@ private void TryCommitTransform(bool synchronize = false, bool settingState = fa
childNetworkTransform.OnNetworkTick(true);
}
}

// Synchronize any parented children with the parent's motion
foreach (var child in m_ParentedChildren)
{
// Synchronize any nested NetworkTransforms of the child with the parent's
foreach (var childNetworkTransform in child.NetworkTransforms)
{
if (childNetworkTransform.CanCommitToTransform)
{
childNetworkTransform.OnNetworkTick(true);
}
}
}
}
}
}
Expand Down Expand Up @@ -2221,13 +2208,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<NetworkObject>();
var parentNetworkObject = NetworkObject.transform.parent.GetComponent<NetworkObject>();

// In-scene placed NetworkObjects parented under a GameObject with no
// NetworkObject preserve their lossyScale when synchronizing.
Expand Down Expand Up @@ -3363,19 +3348,6 @@ private void OnNetworkStateChanged(NetworkTransformState oldState, NetworkTransf
childNetworkTransform.OnNetworkTick(true);
}
}

// Synchronize any parented children with the parent's motion
foreach (var child in m_ParentedChildren)
{
// Synchronize any nested NetworkTransforms of the child with the parent's
foreach (var childNetworkTransform in child.NetworkTransforms)
{
if (childNetworkTransform.CanCommitToTransform)
{
childNetworkTransform.OnNetworkTick(true);
}
}
}
}

// Provide notifications when the state has been updated
Expand Down Expand Up @@ -3634,8 +3606,6 @@ internal override void InternalOnNetworkPreSpawn(ref NetworkManager networkManag
/// <inheritdoc/>
public override void OnNetworkSpawn()
{
m_ParentedChildren.Clear();

Initialize();

if (CanCommitToTransform && !SwitchTransformSpaceWhenParented)
Expand All @@ -3647,7 +3617,6 @@ public override void OnNetworkSpawn()

private void CleanUpOnDestroyOrDespawn()
{
m_ParentedChildren.Clear();
#if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D
var forUpdate = !m_UseRigidbodyForMotion;
#else
Expand Down Expand Up @@ -3861,7 +3830,6 @@ protected override void OnOwnershipChanged(ulong previous, ulong current)
}

internal bool IsNested;
private List<NetworkObject> m_ParentedChildren = new List<NetworkObject>();

private bool m_IsFirstNetworkTransform;

Expand Down Expand Up @@ -4694,7 +4662,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.<br />
/// <see cref="NetworkTimeSystem.TickLatency"/>
/// </remarks>
public static int InterpolationBufferTickOffset = 0;
public static int InterpolationBufferTickOffset;
internal static float GetTickLatency(NetworkManager networkManager)
{
if (networkManager.IsListening)
Expand Down Expand Up @@ -4800,6 +4768,21 @@ public NetworkTransformTickRegistration(NetworkManager networkManager)
}
}
private static int s_TickSynchPosition;

#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetStaticsOnLoad()
Comment thread
noellie-velez marked this conversation as resolved.
Outdated
{
CurrentTick = 0;
TrackStateUpdateId = false;
AssignDefaultInterpolationType = false;
DefaultInterpolationType = default;
s_NetworkTickRegistration = new Dictionary<NetworkManager, NetworkTransformTickRegistration>();
InterpolationBufferTickOffset = 0;
s_TickSynchPosition = 0;
}
#endif

private int m_NextTickSync;

internal void RegisterForTickSynchronization()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Comment thread
noellie-velez marked this conversation as resolved.
Outdated
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetStaticsOnLoad() => s_QuatAbsValues = Quaternion.identity;
#endif

/// <summary>
/// Compresses a Quaternion into an unsigned integer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public struct ContactEventHandlerInfo
/// </summary>
public bool ProvideNonRigidBodyContactEvents;
/// <summary>
/// When set to true, the <see cref="RigidbodyContactEventManager"/> will prioritize invoking <see cref="IContactEventHandler.ContactEvent(ulong, Vector3, Rigidbody, Vector3, bool, Vector3)"/> <br /></br>
/// When set to true, the <see cref="RigidbodyContactEventManager"/> will prioritize invoking <see cref="IContactEventHandler.ContactEvent(ulong, Vector3, Rigidbody, Vector3, bool, Vector3)"/> <br />
/// if it is the 2nd colliding body in the contact pair being processed. With distributed authority, setting this value to true when a <see cref="NetworkObject"/> is owned by the local client <br />
/// will assure <see cref="IContactEventHandler.ContactEvent(ulong, Vector3, Rigidbody, Vector3, bool, Vector3)"/> is only invoked on the authoritative side.
/// </summary>
Expand Down Expand Up @@ -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
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> CommandLineArguments = new List<string>();

// Invoked upon application start, after scene load
[RuntimeInitializeOnLoadMethod]
private static void ParseCommandLineArguments()
private static List<string> s_CommandLineArguments = new List<string>(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<string>(Environment.GetCommandLineArgs());
s_CommandLineArguments = new List<string>(Environment.GetCommandLineArgs());
}
#endif

/// <summary>
/// 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
/// </summary>
/// <param name="arg">The name of the argument</param>
/// <returns><see cref="string"/>Value of the command line argument passed in.</returns>
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;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEngine;
#endif
Comment thread
noellie-velez marked this conversation as resolved.
Outdated

namespace Unity.Netcode
{
Expand All @@ -14,6 +17,10 @@ internal static class ComponentFactory
internal delegate object CreateObjectDelegate(NetworkManager networkManager);

private static Dictionary<Type, CreateObjectDelegate> s_Delegates = new Dictionary<Type, CreateObjectDelegate>();
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetStaticsOnLoad() => s_Delegates = new Dictionary<Type, CreateObjectDelegate>();
#endif

/// <summary>
/// Instantiates an instance of a given interface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1299,8 +1299,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'
Expand Down
13 changes: 13 additions & 0 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1796,6 +1796,19 @@ internal abstract class NetcodeAnalytics
internal delegate void ResetNetworkManagerDelegate(NetworkManager manager);

internal static ResetNetworkManagerDelegate OnNetworkManagerReset;
//We already are in an #if UNITY_ENGINE def
Comment thread
noellie-velez marked this conversation as resolved.
Outdated
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetStaticsOnLoad()
{
Singleton = null;
OnInstantiated = null;
OnDestroying = null;
OnSingletonReady = null;
OnNetworkManagerReset = null;
IsDistributedAuthority = false;
s_SerializedType = new List<Type>();
DisableNotOptimizedSerializedType = false;
}

private void Reset()
Comment thread
noellie-velez marked this conversation as resolved.
{
Expand Down
9 changes: 9 additions & 0 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1725,6 +1725,11 @@ internal void SetIsDestroying()
IsDestroying = true;
}

private void OnDisable()
{
SceneManager.activeSceneChanged -= CurrentlyActiveSceneChanged;
}

private void OnDestroy()
{
// Apply the is destroying flag
Expand Down Expand Up @@ -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<NetworkObject> OrphanChildren = new HashSet<NetworkObject>();
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetStaticsOnLoad() => OrphanChildren = new HashSet<NetworkObject>();
#endif

internal bool ApplyNetworkParenting(bool removeParent = false, bool ignoreNotSpawned = false, bool orphanedChildPass = false, bool enableNotification = true)
{
Expand Down
36 changes: 23 additions & 13 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkUpdateLoop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,19 @@ public enum NetworkUpdateStage : byte
/// </summary>
public static class NetworkUpdateLoop
{
private static Dictionary<NetworkUpdateStage, HashSet<INetworkUpdateSystem>> s_UpdateSystem_Sets;
private static Dictionary<NetworkUpdateStage, INetworkUpdateSystem[]> s_UpdateSystem_Arrays;
private const int k_UpdateSystem_InitialArrayCapacity = 1024;
private static Dictionary<NetworkUpdateStage, HashSet<INetworkUpdateSystem>> s_UpdateSystemSets;
private static Dictionary<NetworkUpdateStage, INetworkUpdateSystem[]> s_UpdateSystemArrays;
private const int k_UpdateSystemInitialArrayCapacity = 1024;

static NetworkUpdateLoop()
{
s_UpdateSystem_Sets = new Dictionary<NetworkUpdateStage, HashSet<INetworkUpdateSystem>>();
s_UpdateSystem_Arrays = new Dictionary<NetworkUpdateStage, INetworkUpdateSystem[]>();
s_UpdateSystemSets = new Dictionary<NetworkUpdateStage, HashSet<INetworkUpdateSystem>>();
s_UpdateSystemArrays = new Dictionary<NetworkUpdateStage, INetworkUpdateSystem[]>();

foreach (NetworkUpdateStage updateStage in Enum.GetValues(typeof(NetworkUpdateStage)))
{
s_UpdateSystem_Sets.Add(updateStage, new HashSet<INetworkUpdateSystem>());
s_UpdateSystem_Arrays.Add(updateStage, new INetworkUpdateSystem[k_UpdateSystem_InitialArrayCapacity]);
s_UpdateSystemSets.Add(updateStage, new HashSet<INetworkUpdateSystem>());
s_UpdateSystemArrays.Add(updateStage, new INetworkUpdateSystem[k_UpdateSystemInitialArrayCapacity]);
}
}

Expand All @@ -105,19 +105,19 @@ public static void RegisterAllNetworkUpdates(this INetworkUpdateSystem updateSys
/// <param name="updateStage">The <see cref="NetworkUpdateStage"/> being registered for the <see cref="INetworkUpdateSystem"/> implementation</param>
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);
Expand Down Expand Up @@ -149,13 +149,13 @@ public static void UnregisterAllNetworkUpdates(this INetworkUpdateSystem updateS
/// <param name="updateStage">The <see cref="NetworkUpdateStage"/> to be deregistered from the <see cref="INetworkUpdateSystem"/> implementation</param>
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);
Expand All @@ -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++)
{
Expand Down Expand Up @@ -291,6 +291,16 @@ public static PlayerLoopSystem CreateLoopSystem()
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void Initialize()
{
#if UNITY_EDITOR
s_UpdateSystemSets = new Dictionary<NetworkUpdateStage, HashSet<INetworkUpdateSystem>>();
s_UpdateSystemArrays = new Dictionary<NetworkUpdateStage, INetworkUpdateSystem[]>();
foreach (NetworkUpdateStage updateStage in Enum.GetValues(typeof(NetworkUpdateStage)))
{
s_UpdateSystemSets.Add(updateStage, new HashSet<INetworkUpdateSystem>());
s_UpdateSystemArrays.Add(updateStage, new INetworkUpdateSystem[k_UpdateSystemInitialArrayCapacity]);
}
UpdateStage = default;
#endif
UnregisterLoopSystems();
RegisterLoopSystems();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.Collections.Generic;
using Unity.Collections;
#if UNITY_EDITOR
using UnityEngine;
Comment thread
noellie-velez marked this conversation as resolved.
Outdated
#endif

namespace Unity.Netcode
{
Expand Down Expand Up @@ -96,6 +99,10 @@ public virtual unsafe void CleanupStaleTriggers()
/// Used for testing purposes
/// </summary>
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)
{
Expand Down
Loading