diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index c4b0af9a6f..ed55793aba 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -12,7 +12,9 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Changed -- Improve performance of `NetworkBehavior`. (#3915) + +- Improve performance of `NetworkBehaviour`. (#3915) +- Improve performance of `NetworkTransform`. (#3907) - Improve performance of `NetworkRigidbodyBase`. (#3906) - Improve performance of `NetworkAnimator`. (#3905) diff --git a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs index 64e9bc0b95..d321014875 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs @@ -1621,10 +1621,11 @@ internal bool SynchronizeScale public bool CanCommitToTransform { get; protected set; } /// - /// Internally used by to keep track of the instance assigned to this + /// Internally used by to keep track of the instance assigned to /// this derived class instance. /// protected NetworkManager m_CachedNetworkManager; + private int m_CachedTickRate; /// /// Helper method that returns the space relative position of the transform. @@ -2136,9 +2137,8 @@ private bool CheckForStateChange(ref NetworkTransformState networkState, bool is // We compare against the NetworkTickSystem version since ServerTime is set when updating ticks if (UseUnreliableDeltas && !isSynchronization && m_DeltaSynch && m_NextTickSync <= CurrentTick) { - // TODO-CACHE: m_CachedNetworkManager.NetworkConfig.TickRate value // Increment to the next frame synch tick position for this instance - m_NextTickSync += (int)m_CachedNetworkManager.NetworkConfig.TickRate; + m_NextTickSync += m_CachedTickRate; // If we are teleporting, we do not need to send a frame synch for this tick slot // as a "frame synch" really is effectively just a teleport. isAxisSync = !flagStates.IsTeleportingNextFrame; @@ -2606,7 +2606,7 @@ private void OnNetworkTick(bool isCalledFromParent = false) } else // If we are no longer authority, unsubscribe to the tick event { - DeregisterForTickUpdate(this); + DeregisterForTickUpdate(); } } #endregion @@ -3537,7 +3537,7 @@ private void ApplyPlayerTransformState() /// /// For dynamically spawned NetworkObjects, when the non-authority instance's client is already connected and - /// the SynchronizeState is still pending synchronization then we want to finalize the synchornization at this time. + /// the SynchronizeState is still pending synchronization then we want to finalize the synchronization at this time. /// protected internal override void InternalOnNetworkPostSpawn() { @@ -3550,7 +3550,7 @@ protected internal override void InternalOnNetworkPostSpawn() // Then we want to: // - Force the "IsSynchronizing" flag so the NetworkTransform has its state updated properly and runs through the initialization again. // - Make sure the SynchronizingState is updated to the instantiated prefab's default flags/settings. - if (NetworkManager.IsServer && !NetworkManager.DistributedAuthorityMode && !IsOwner && !OnIsServerAuthoritative() && !SynchronizeState.IsSynchronizing) + if (m_CachedNetworkManager.IsServer && !m_CachedNetworkManager.DistributedAuthorityMode && !IsOwner && !OnIsServerAuthoritative() && !SynchronizeState.IsSynchronizing) { // Handle the first/root NetworkTransform slightly differently to have a sequenced synchronization of like authority nested NetworkTransform components if (m_IsFirstNetworkTransform) @@ -3578,7 +3578,7 @@ protected internal override void InternalOnNetworkPostSpawn() } // Standard non-authority synchronization is handled here - if (!CanCommitToTransform && NetworkManager.IsConnectedClient && SynchronizeState.IsSynchronizing) + if (!CanCommitToTransform && m_CachedNetworkManager.IsConnectedClient && SynchronizeState.IsSynchronizing) { NonAuthorityFinalizeSynchronization(); } @@ -3631,7 +3631,6 @@ internal override void InternalOnNetworkPreSpawn(ref NetworkManager networkManag public override void OnNetworkSpawn() { m_ParentedChildren.Clear(); - m_CachedNetworkManager = NetworkManager; Initialize(); @@ -3639,6 +3638,7 @@ public override void OnNetworkSpawn() { SetState(GetSpaceRelativePosition(), GetSpaceRelativeRotation(), GetScale(), false); } + base.OnNetworkSpawn(); } private void CleanUpOnDestroyOrDespawn() @@ -3651,10 +3651,10 @@ private void CleanUpOnDestroyOrDespawn() #endif if (m_CachedNetworkObject != null) { - NetworkManager?.NetworkTransformRegistration(m_CachedNetworkObject, forUpdate, false); + m_CachedNetworkManager?.NetworkTransformRegistration(m_CachedNetworkObject, forUpdate, false); } - DeregisterForTickUpdate(this); + DeregisterForTickUpdate(); CanCommitToTransform = false; } @@ -3697,7 +3697,7 @@ protected virtual void OnInitialize(ref NetworkVariable r /// private void ResetInterpolatedStateToCurrentAuthoritativeState() { - var serverTime = NetworkManager.ServerTime.Time; + var serverTime = m_CachedNetworkManager.ServerTime.Time; #if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D var position = m_UseRigidbodyForMotion ? m_NetworkRigidbodyInternal.GetPosition() : GetSpaceRelativePosition(); var rotation = m_UseRigidbodyForMotion ? m_NetworkRigidbodyInternal.GetRotation() : GetSpaceRelativeRotation(); @@ -3719,7 +3719,7 @@ private void ResetInterpolatedStateToCurrentAuthoritativeState() } private NetworkObject m_CachedNetworkObject; /// - /// The internal initialzation method to allow for internal API adjustments + /// The internal initialization method to allow for internal API adjustments /// /// private void InternalInitialization(bool isOwnershipChange = false) @@ -3729,9 +3729,10 @@ private void InternalInitialization(bool isOwnershipChange = false) return; } m_CachedNetworkObject = NetworkObject; + m_CachedTickRate = (int)m_CachedNetworkManager.NetworkConfig.TickRate; // Determine if this is the first NetworkTransform in the associated NetworkObject's list - m_IsFirstNetworkTransform = NetworkObject.NetworkTransforms[0] == this; + m_IsFirstNetworkTransform = m_CachedNetworkObject.NetworkTransforms[0] == this; if (m_CachedNetworkManager && m_CachedNetworkManager.DistributedAuthorityMode) { @@ -3755,9 +3756,9 @@ private void InternalInitialization(bool isOwnershipChange = false) var currentPosition = GetSpaceRelativePosition(); var currentRotation = GetSpaceRelativeRotation(); - if (NetworkManager.DistributedAuthorityMode) + if (m_CachedNetworkManager.DistributedAuthorityMode) { - RegisterNetworkManagerForTickUpdate(NetworkManager); + RegisterNetworkManagerForTickUpdate(m_CachedNetworkManager); } #if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D @@ -3793,7 +3794,7 @@ private void InternalInitialization(bool isOwnershipChange = false) m_InternalCurrentPosition = currentPosition; m_LastStateTargetPosition = currentPosition; - RegisterForTickUpdate(this); + RegisterForTickUpdate(); if (UseHalfFloatPrecision && isOwnershipChange && !IsServerAuthoritative() && Interpolate) { @@ -3813,7 +3814,7 @@ private void InternalInitialization(bool isOwnershipChange = false) // Non-authority needs to be added to updates for interpolation and applying state purposes m_CachedNetworkManager.NetworkTransformRegistration(NetworkObject, forUpdate, true); // Remove this instance from the tick update - DeregisterForTickUpdate(this); + DeregisterForTickUpdate(); ResetInterpolatedStateToCurrentAuthoritativeState(); m_InternalCurrentPosition = currentPosition; m_LastStateTargetPosition = currentPosition; @@ -3941,7 +3942,7 @@ internal override void InternalOnNetworkObjectParentChanged(NetworkObject parent if (LastTickSync == m_LocalAuthoritativeNetworkState.GetNetworkTick()) { m_InternalCurrentPosition = m_LastStateTargetPosition = GetSpaceRelativePosition(); - m_PositionInterpolator.ResetTo(m_PositionInterpolator.Parent, m_InternalCurrentPosition, NetworkManager.ServerTime.Time); + m_PositionInterpolator.ResetTo(m_PositionInterpolator.Parent, m_InternalCurrentPosition, m_CachedNetworkManager.ServerTime.Time); if (InLocalSpace) { transform.localPosition = m_InternalCurrentPosition; @@ -3973,7 +3974,7 @@ internal override void InternalOnNetworkObjectParentChanged(NetworkObject parent { m_InternalCurrentRotation = GetSpaceRelativeRotation(); m_TargetRotation = m_InternalCurrentRotation.eulerAngles; - m_RotationInterpolator.ResetTo(m_RotationInterpolator.Parent, m_InternalCurrentRotation, NetworkManager.ServerTime.Time); + m_RotationInterpolator.ResetTo(m_RotationInterpolator.Parent, m_InternalCurrentRotation, m_CachedNetworkManager.ServerTime.Time); if (InLocalSpace) { transform.localRotation = m_InternalCurrentRotation; @@ -4596,7 +4597,7 @@ internal void TransformStateUpdate() { // TODO: Investigate where this state should be applied or just discarded. // For now, discard the state if we assumed ownership. - // Debug.Log($"[Client-{NetworkManager.LocalClientId}] Ignoring inbound update from Client-{0} and parentUpdated:{isParentingDirective}!"); + // Debug.Log($"[Client-{m_CachedNetworkManager.LocalClientId}] Ignoring inbound update from Client-{0} and parentUpdated:{isParentingDirective}!"); return; } // Store the previous/old state @@ -4653,17 +4654,17 @@ private void UpdateTransformState() { continue; } - if (!NetworkObject.Observers.Contains(clientId)) + if (!m_CachedNetworkObject.Observers.Contains(clientId)) { continue; } - NetworkManager.MessageManager.SendMessage(ref m_OutboundMessage, networkDelivery, clientId); + m_CachedNetworkManager.MessageManager.SendMessage(ref m_OutboundMessage, networkDelivery, clientId); } } else { // Clients (owner authoritative) send messages to the server-host - NetworkManager.MessageManager.SendMessage(ref m_OutboundMessage, networkDelivery, NetworkManager.ServerClientId); + m_CachedNetworkManager.MessageManager.SendMessage(ref m_OutboundMessage, networkDelivery, NetworkManager.ServerClientId); } m_LocalAuthoritativeNetworkState.LastSerializedSize = m_OutboundMessage.BytesWritten; } @@ -4802,7 +4803,7 @@ public NetworkTransformTickRegistration(NetworkManager networkManager) internal void RegisterForTickSynchronization() { s_TickSynchPosition++; - m_NextTickSync = NetworkManager.ServerTime.Tick + (s_TickSynchPosition % (int)NetworkManager.NetworkConfig.TickRate); + m_NextTickSync = m_CachedNetworkManager.ServerTime.Tick + (s_TickSynchPosition % m_CachedTickRate); } private static void RegisterNetworkManagerForTickUpdate(NetworkManager networkManager) @@ -4818,36 +4819,34 @@ private static void RegisterNetworkManagerForTickUpdate(NetworkManager networkMa /// If a NetworkTransformTickRegistration has not yet been registered for the NetworkManager /// instance, then create an entry. /// - /// - private static void RegisterForTickUpdate(NetworkTransform networkTransform) + private void RegisterForTickUpdate() { - if (!networkTransform.NetworkManager.DistributedAuthorityMode && !s_NetworkTickRegistration.ContainsKey(networkTransform.NetworkManager)) + if (!m_CachedNetworkManager.DistributedAuthorityMode && !s_NetworkTickRegistration.ContainsKey(m_CachedNetworkManager)) { - s_NetworkTickRegistration.Add(networkTransform.NetworkManager, new NetworkTransformTickRegistration(networkTransform.NetworkManager)); + s_NetworkTickRegistration.Add(m_CachedNetworkManager, new NetworkTransformTickRegistration(m_CachedNetworkManager)); } - networkTransform.RegisterForTickSynchronization(); - s_NetworkTickRegistration[networkTransform.NetworkManager].NetworkTransforms.Add(networkTransform); + RegisterForTickSynchronization(); + s_NetworkTickRegistration[m_CachedNetworkManager].NetworkTransforms.Add(this); } /// /// If a NetworkTransformTickRegistration exists for the NetworkManager instance, then this will /// remove the NetworkTransform instance from the single tick update entry point. /// - /// - private static void DeregisterForTickUpdate(NetworkTransform networkTransform) + private void DeregisterForTickUpdate() { - if (networkTransform.NetworkManager == null) + if (m_CachedNetworkManager == null) { return; } - if (s_NetworkTickRegistration.ContainsKey(networkTransform.NetworkManager)) + if (s_NetworkTickRegistration.ContainsKey(m_CachedNetworkManager)) { - s_NetworkTickRegistration[networkTransform.NetworkManager].NetworkTransforms.Remove(networkTransform); - if (!networkTransform.NetworkManager.DistributedAuthorityMode && s_NetworkTickRegistration[networkTransform.NetworkManager].NetworkTransforms.Count == 0) + s_NetworkTickRegistration[m_CachedNetworkManager].NetworkTransforms.Remove(this); + if (!m_CachedNetworkManager.DistributedAuthorityMode && s_NetworkTickRegistration[m_CachedNetworkManager].NetworkTransforms.Count == 0) { - var registrationEntry = s_NetworkTickRegistration[networkTransform.NetworkManager]; + var registrationEntry = s_NetworkTickRegistration[m_CachedNetworkManager]; registrationEntry.Remove(); } } diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkTransformMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkTransformMessage.cs index a5c279c7c3..7497d54ab2 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkTransformMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NetworkTransformMessage.cs @@ -106,7 +106,7 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int var transform = networkObject.ChildNetworkBehaviours[networkBehaviourId] as NetworkTransform; if (transform == null) { - Debug.LogError($"[{nameof(NetworkTransformMessage)}][Invalid] Targeted {nameof(NetworkTransform)}, {nameof(NetworkBehaviour.NetworkBehaviourId)} ({networkBehaviourId}), does not exist! Make sure you are not spawning {nameof(NetworkObject)}s with disabled {nameof(GameObject)}s that have {nameof(NetworkBehaviour)} components on them."); + Debug.LogError($"[{nameof(NetworkTransformMessage)}][Invalid] Targeted {nameof(NetworkTransform)}, {nameof(NetworkBehaviour.NetworkBehaviourId)} ({networkBehaviourId}), does not exist on {networkObject.name}! Make sure you are not spawning {nameof(NetworkObject)}s with disabled {nameof(GameObject)}s that have {nameof(NetworkBehaviour)} components on them."); return false; }