Skip to content

Commit 789f375

Browse files
fix: NetworkTransport early and post late updates (#3113)
* fix Break out the UnityTransport's Update method into two methods: EarlyUpdate and PostLateUpdate. * update Modifications to NetworkManager to invoke the newly adding EarlyUpdate and PostLateUpdate methods. * update Adjusting the job handle name. Migrating the m_FlushSendJobHandle.Complete(); outside of the driver IsCreated check to avoid any potential job safety issues. * style removing unused Update method and removing the Unity.Netcode.Transports.UTP namespace reference. * update Removing the job handle stuff as that could potentially break users trying to get RTT during OnGUI. * test fix Adjusting the UnityTransport tests to simulate the NetworkManager invoking the EarlyUpdate and PostLateUpdate methods. Adding event processing in shutdown primarily for integration testing to handle any pending events prior to shutting down the transport. This resolves the issue with the UnitTransportConnectionTests failing in areas where it was just waiting and not invoking the EarlyUpdate and PostLateUpdate methods. * test - fix Approaching the issue differently by adding a UnityTransportTestComponent that registers with the playerloop update stages needed to properly handle message processing. * test Removing the unused additional script and namespace reference. * test removing some more unused code and the namespace reference. * style removing some CRs and unused local var. * test - fix Removing whitespace issue. Setting velocity to zero after moving and after waiting. * update Adding change log entries. Found the culprit with the transform ownership instability. Moving an object can give it velocity which if there is enough time that passes between updates then fixed update will apply enough velocity motion to move the object and it will continue to move. Increased mass and linearDampening and setting the linear velocity to zero in the appropriate places.
1 parent d709df4 commit 789f375

File tree

9 files changed

+422
-165
lines changed

9 files changed

+422
-165
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ Additional documentation and release notes are available at [Multiplayer Documen
1010

1111
### Added
1212

13+
- Added `NetworkTransport.OnEarlyUpdate` and `NetworkTransport.OnPostLateUpdate` methods to provide more control over handling transport related events at the start and end of each frame. (#3113)
14+
1315
### Fixed
1416

17+
- Fixed issue where queued UnitTransport (NetworkTransport) message batches were being sent on the next frame. They are now sent at the end of the frame during `PostLateUpdate`. (#3113)
1518
- Fixed issue where `NotOwnerRpcTarget` or `OwnerRpcTarget` were not using their replacements `NotAuthorityRpcTarget` and `AuthorityRpcTarget` which would invoke a warning. (#3111)
1619
- Fixed issue where client is removed as an observer from spawned objects when their player instance is despawned. (#3110)
1720
- Fixed issue where `NetworkAnimator` would statically allocate write buffer space for `Animator` parameters that could cause a write error if the number of parameters exceeded the space allocated. (#3108)

com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,13 +291,18 @@ public void NetworkUpdate(NetworkUpdateStage updateStage)
291291
case NetworkUpdateStage.EarlyUpdate:
292292
{
293293
UpdateTopology();
294+
295+
// Handle processing any new connections or transport events
296+
NetworkConfig.NetworkTransport.EarlyUpdate();
297+
294298
ConnectionManager.ProcessPendingApprovals();
295299
ConnectionManager.PollAndHandleNetworkEvents();
296300

297301
DeferredMessageManager.ProcessTriggers(IDeferredNetworkMessageManager.TriggerType.OnNextFrame, 0);
298302

299303
AnticipationSystem.SetupForUpdate();
300304
MessageManager.ProcessIncomingMessageQueue();
305+
301306
MessageManager.CleanupDisconnectedClients();
302307
AnticipationSystem.ProcessReanticipation();
303308
}
@@ -379,6 +384,9 @@ public void NetworkUpdate(NetworkUpdateStage updateStage)
379384
// Metrics update needs to be driven by NetworkConnectionManager's update to assure metrics are dispatched after the send queue is processed.
380385
MetricsManager.UpdateMetrics();
381386

387+
// Handle sending any pending transport messages
388+
NetworkConfig.NetworkTransport.PostLateUpdate();
389+
382390
// TODO: Determine a better way to handle this
383391
NetworkObject.VerifyParentingStatus();
384392

com.unity.netcode.gameobjects/Runtime/Transports/NetworkTransport.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,45 @@ protected void InvokeOnTransportEvent(NetworkEvent eventType, ulong clientId, Ar
107107
/// /// <param name="networkManager">optionally pass in NetworkManager</param>
108108
public abstract void Initialize(NetworkManager networkManager = null);
109109

110+
/// <summary>
111+
/// Invoked by NetworkManager at the beginning of its EarlyUpdate.
112+
/// For order of operations see: <see cref="NetworkManager.NetworkUpdate(NetworkUpdateStage)"/>
113+
/// </summary>
114+
/// Useful to handle processing any transport-layer events such as processing inbound messages or changes in connection state(s).
115+
/// </remarks>
116+
protected virtual void OnEarlyUpdate()
117+
{
118+
119+
}
120+
121+
/// <summary>
122+
/// Invoked by NetworkManager at the beginning of its EarlyUpdate
123+
/// </summary>
124+
internal void EarlyUpdate()
125+
{
126+
OnEarlyUpdate();
127+
}
128+
129+
/// <summary>
130+
/// Invoked by NetworkManager towards the end of the PostLateUpdate.
131+
/// For order of operations see: <see cref="NetworkManager.NetworkUpdate(NetworkUpdateStage)"/>
132+
/// </summary>
133+
/// <remarks>
134+
/// Useful to handle any end of frame transport tasks such as sending queued transport messages.
135+
/// </remarks>
136+
protected virtual void OnPostLateUpdate()
137+
{
138+
139+
}
140+
141+
/// <summary>
142+
/// Invoked by NetworkManager towards the end of the PostLateUpdate
143+
/// </summary>
144+
internal void PostLateUpdate()
145+
{
146+
OnPostLateUpdate();
147+
}
148+
110149
protected virtual NetworkTopologyTypes OnCurrentTopology()
111150
{
112151
return NetworkTopologyTypes.ClientServer;

com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -944,17 +944,13 @@ private bool ProcessEvent()
944944
return false;
945945
}
946946

947-
private void Update()
947+
/// <summary>
948+
/// Handles accepting new connections and processing transport events.
949+
/// </summary>
950+
protected override void OnEarlyUpdate()
948951
{
949952
if (m_Driver.IsCreated)
950953
{
951-
foreach (var kvp in m_SendQueue)
952-
{
953-
SendBatchedMessages(kvp.Key, kvp.Value);
954-
}
955-
956-
m_Driver.ScheduleUpdate().Complete();
957-
958954
if (m_ProtocolType == ProtocolType.RelayUnityTransport && m_Driver.GetRelayConnectionStatus() == RelayConnectionStatus.AllocationInvalid)
959955
{
960956
Debug.LogError("Transport failure! Relay allocation needs to be recreated, and NetworkManager restarted. " +
@@ -964,15 +960,38 @@ private void Update()
964960
return;
965961
}
966962

963+
m_Driver.ScheduleUpdate().Complete();
964+
965+
// Process any new connections
967966
while (AcceptConnection() && m_Driver.IsCreated)
968967
{
969968
;
970969
}
971970

971+
// Process any transport events (i.e. connect, disconnect, data, etc)
972972
while (ProcessEvent() && m_Driver.IsCreated)
973973
{
974974
;
975975
}
976+
}
977+
base.OnEarlyUpdate();
978+
}
979+
980+
/// <summary>
981+
/// Handles sending any queued batched messages.
982+
/// </summary>
983+
protected override void OnPostLateUpdate()
984+
{
985+
if (m_Driver.IsCreated)
986+
{
987+
foreach (var kvp in m_SendQueue)
988+
{
989+
SendBatchedMessages(kvp.Key, kvp.Value);
990+
}
991+
992+
// Schedule a flush send as the last transport action for the
993+
// current frame.
994+
m_Driver.ScheduleFlushSend(default).Complete();
976995

977996
#if MULTIPLAYER_TOOLS_1_0_0_PRE_7
978997
if (m_NetworkManager)
@@ -981,6 +1000,7 @@ private void Update()
9811000
}
9821001
#endif
9831002
}
1003+
base.OnPostLateUpdate();
9841004
}
9851005

9861006
private void OnDestroy()
@@ -1452,6 +1472,11 @@ public override void Shutdown()
14521472
{
14531473
if (m_Driver.IsCreated)
14541474
{
1475+
while (ProcessEvent() && m_Driver.IsCreated)
1476+
{
1477+
;
1478+
}
1479+
14551480
// Flush all send queues to the network. NGO can be configured to flush its message
14561481
// queue on shutdown. But this only calls the Send() method, which doesn't actually
14571482
// get anything to the network.

0 commit comments

Comments
 (0)