Skip to content

Commit 4df63ea

Browse files
refactor
Relatively large change: - Preserving order of operations by making the default network delivery be reliable fragmented sequenced with the exception of named, unnamed, and any message types adjusted explicitly by user code to use a different network delivery method. - Adjusted parenting directive to allow the server to force a parenting directive on a NetworkTransform it does not have the motion authority over. - The NetworkObjects to show now will be also processed in-between ticks to preserve order of operations. - NetworkObjects pending to be shown on the same frame as the tick update will still be processed during the tick update.
1 parent cf27a00 commit 4df63ea

File tree

18 files changed

+275
-150
lines changed

18 files changed

+275
-150
lines changed

com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2529,6 +2529,7 @@ internal void UpdatePositionInterpolator(Vector3 position, double time, bool res
25292529
{
25302530
if (resetInterpolator)
25312531
{
2532+
m_PositionInterpolator.InLocalSpace = InLocalSpace;
25322533
m_PositionInterpolator.ResetTo(position, time);
25332534
}
25342535
else
@@ -2999,6 +3000,7 @@ private void ApplyTeleportingState(NetworkTransformState newState)
29993000

30003001
if (Interpolate)
30013002
{
3003+
m_RotationInterpolator.InLocalSpace = InLocalSpace;
30023004
m_RotationInterpolator.ResetTo(currentRotation, sentTime);
30033005
}
30043006
}
@@ -3195,11 +3197,6 @@ protected virtual void OnBeforeUpdateTransformState()
31953197
/// </summary>
31963198
private void OnNetworkStateChanged(NetworkTransformState oldState, NetworkTransformState newState)
31973199
{
3198-
if (!NetworkObject.IsSpawned || CanCommitToTransform)
3199-
{
3200-
return;
3201-
}
3202-
32033200
// If we are using UseUnreliableDeltas and our old state tick is greater than the new state tick,
32043201
// then just ignore the newstate. This avoids any scenario where the new state is out of order
32053202
// from the old state (with unreliable traffic and/or mixed unreliable and reliable)
@@ -4419,12 +4416,13 @@ internal NetworkTransformState OutboundState
44194416
/// Invoked by <see cref="NetworkTransformMessage"/> to update the transform state
44204417
/// </summary>
44214418
/// <param name="networkTransformState"></param>
4422-
internal void TransformStateUpdate(ulong senderId, bool parentUpdated)
4419+
internal void TransformStateUpdate(ulong senderId, bool isParentingDirective)
44234420
{
4424-
if (CanCommitToTransform)
4421+
if (!IsSpawned || (CanCommitToTransform && !isParentingDirective))
44254422
{
44264423
// TODO: Investigate where this state should be applied or just discarded.
44274424
// For now, discard the state if we assumed ownership.
4425+
Debug.LogError($"[Client-{NetworkManager.LocalClientId}] Ignoring inbound update from Client-{0} and parentUpdated:{isParentingDirective}!");
44284426
return;
44294427
}
44304428
// Store the previous/old state
@@ -4440,10 +4438,22 @@ internal void TransformStateUpdate(ulong senderId, bool parentUpdated)
44404438
// Used to send outbound messages
44414439
private NetworkTransformMessage m_OutboundMessage = new NetworkTransformMessage();
44424440

4441+
/// <summary>
4442+
/// Only invoked by the authority.
4443+
/// (motion or server)
4444+
/// </summary>
44434445
internal void ParentingUpdate(NetworkObject parent, bool worldPositionStays)
44444446
{
4447+
// Super-edge case when spawning an object with ownership and then immeidatley
4448+
// parenting. If so, update the current position and rotation values.
4449+
if (!CanCommitToTransform && IsServer)
4450+
{
4451+
m_InternalCurrentPosition = transform.localPosition;
4452+
m_InternalCurrentRotation = transform.localRotation;
4453+
}
44454454
InLocalSpace = parent;
44464455
m_OutboundMessage.SetParent(new NetworkObjectReference(parent), worldPositionStays);
4456+
44474457
var transformToCommit = transform;
44484458
CheckForStateChange(ref m_LocalAuthoritativeNetworkState, ref transformToCommit, false, forceState: true);
44494459
UpdateTransformState();
@@ -4465,31 +4475,56 @@ internal void UpdateParenting(NetworkObjectReference parent, bool worldPositionS
44654475
if (!removeParent)
44664476
{
44674477
// Convert the world space transform values to the local space of the new transform
4468-
m_InternalCurrentPosition = parentObject.transform.InverseTransformPoint(transform.position);
4469-
m_InternalCurrentRotation = Quaternion.Inverse(parentObject.transform.rotation) * m_InternalCurrentRotation;
4478+
if (SynchronizePosition)
4479+
{
4480+
m_InternalCurrentPosition = parentObject.transform.InverseTransformPoint(transform.position);
4481+
}
4482+
if (SynchronizeRotation)
4483+
{
4484+
m_InternalCurrentRotation = Quaternion.Inverse(parentObject.transform.rotation) * m_InternalCurrentRotation;
4485+
}
44704486

44714487
// If we had a previous parent...
44724488
if (m_PreviousParent && InLocalSpace)
44734489
{
44744490
// Convert the queues to world space relative to the previous parent
44754491
// so when we convert back to local space relative to the new parent
44764492
// the are all already in world space.
4477-
m_PositionInterpolator.ConvertTransformSpace(m_PreviousParent.transform, false);
4478-
m_RotationInterpolator.ConvertTransformSpace(m_PreviousParent.transform, false);
4493+
if (SynchronizePosition)
4494+
{
4495+
m_PositionInterpolator.ConvertTransformSpace(m_PreviousParent.transform, false);
4496+
}
4497+
if (SynchronizeRotation)
4498+
{
4499+
m_RotationInterpolator.ConvertTransformSpace(m_PreviousParent.transform, false);
4500+
}
44794501
}
4502+
InLocalSpace = true;
44804503
// Convert the world space values of the interpolators to local space
4481-
m_PositionInterpolator.ConvertTransformSpace(parentObject.transform, true);
4482-
m_RotationInterpolator.ConvertTransformSpace(parentObject.transform, true);
4504+
if (SynchronizePosition)
4505+
{
4506+
m_PositionInterpolator.ConvertTransformSpace(parentObject.transform, true);
4507+
}
4508+
if (SynchronizeRotation)
4509+
{
4510+
m_RotationInterpolator.ConvertTransformSpace(parentObject.transform, true);
4511+
}
44834512
m_PreviousParent = parentObject;
44844513
}
44854514
else if (m_PreviousParent)
44864515
{
44874516
InLocalSpace = false;
44884517
// Convert everything back to world space values
4489-
m_InternalCurrentPosition = m_PreviousParent.transform.TransformPoint(transform.localPosition);
4490-
m_InternalCurrentRotation = m_PreviousParent.transform.localRotation * m_InternalCurrentRotation;
4491-
m_PositionInterpolator.ConvertTransformSpace(m_PreviousParent.transform, false);
4492-
m_RotationInterpolator.ConvertTransformSpace(m_PreviousParent.transform, false);
4518+
if (SynchronizePosition)
4519+
{
4520+
m_InternalCurrentPosition = m_PreviousParent.transform.TransformPoint(transform.localPosition);
4521+
m_PositionInterpolator.ConvertTransformSpace(m_PreviousParent.transform, false);
4522+
}
4523+
if (SynchronizeRotation)
4524+
{
4525+
m_InternalCurrentRotation = m_PreviousParent.transform.localRotation * m_InternalCurrentRotation;
4526+
m_RotationInterpolator.ConvertTransformSpace(m_PreviousParent.transform, false);
4527+
}
44934528
m_PreviousParent = null;
44944529
}
44954530

@@ -4528,7 +4563,7 @@ private void UpdateTransformState()
45284563
// - If sending an UnrealiableFrameSync or synchronizing the base position of the NetworkDeltaPosition
45294564
var networkDelivery = !UseUnreliableDeltas | m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame | m_LocalAuthoritativeNetworkState.IsSynchronizing
45304565
| m_LocalAuthoritativeNetworkState.UnreliableFrameSync | m_LocalAuthoritativeNetworkState.SynchronizeBaseHalfFloat
4531-
? NetworkDelivery.ReliableSequenced : NetworkDelivery.UnreliableSequenced;
4566+
? MessageDelivery.GetDelivery(NetworkMessageTypes.NetworkTransformMessage) : NetworkDelivery.UnreliableSequenced;
45324567

45334568
// Server-host-dahost always sends updates to all clients (but itself)
45344569
if (IsServer)

com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ private void SendConnectionRequest()
635635
}
636636
}
637637

638-
SendMessage(ref message, NetworkDelivery.ReliableFragmentedSequenced, NetworkManager.ServerClientId);
638+
SendMessage(ref message, MessageDelivery.GetDelivery(NetworkMessageTypes.ConnectionRequest), NetworkManager.ServerClientId);
639639
message.MessageVersions.Dispose();
640640
}
641641

@@ -857,7 +857,7 @@ internal void HandleConnectionApproval(ulong ownerClientId, NetworkManager.Conne
857857
}
858858
if (!MockSkippingApproval)
859859
{
860-
SendMessage(ref message, NetworkDelivery.ReliableFragmentedSequenced, ownerClientId);
860+
SendMessage(ref message, MessageDelivery.GetDelivery(NetworkMessageTypes.ConnectionApproved), ownerClientId);
861861
}
862862
else
863863
{
@@ -987,7 +987,7 @@ internal void ApprovedPlayerSpawn(ulong clientId, uint playerPrefabHash)
987987
message.ObjectInfo.HasParent = false;
988988
message.ObjectInfo.IsPlayerObject = true;
989989
message.ObjectInfo.OwnerClientId = clientId;
990-
var size = SendMessage(ref message, NetworkDelivery.ReliableFragmentedSequenced, clientPair.Key);
990+
var size = SendMessage(ref message, MessageDelivery.GetDelivery(NetworkMessageTypes.CreateObject), clientPair.Key);
991991
NetworkManager.NetworkMetrics.TrackObjectSpawnSent(clientPair.Key, ConnectedClients[clientId].PlayerObject, size);
992992
}
993993
}
@@ -1021,14 +1021,14 @@ internal NetworkClient AddClient(ulong clientId)
10211021
{
10221022
ConnectedClientsList.Add(networkClient);
10231023
}
1024-
1024+
var networkDelivery = MessageDelivery.GetDelivery(NetworkMessageTypes.ClientConnected);
10251025
if (NetworkManager.LocalClientId != clientId)
10261026
{
10271027
if ((!NetworkManager.DistributedAuthorityMode && NetworkManager.IsServer) ||
10281028
(NetworkManager.DistributedAuthorityMode && NetworkManager.NetworkConfig.EnableSceneManagement && NetworkManager.DAHost && NetworkManager.LocalClient.IsSessionOwner))
10291029
{
10301030
var message = new ClientConnectedMessage { ClientId = clientId };
1031-
NetworkManager.MessageManager.SendMessage(ref message, NetworkDelivery.ReliableSequenced, ConnectedClientIds.Where((c) => c != NetworkManager.LocalClientId).ToArray());
1031+
NetworkManager.MessageManager.SendMessage(ref message, networkDelivery, ConnectedClientIds.Where((c) => c != NetworkManager.LocalClientId).ToArray());
10321032
}
10331033
else if (NetworkManager.DistributedAuthorityMode && NetworkManager.NetworkConfig.EnableSceneManagement && NetworkManager.DAHost && !NetworkManager.LocalClient.IsSessionOwner)
10341034
{
@@ -1037,7 +1037,7 @@ internal NetworkClient AddClient(ulong clientId)
10371037
ShouldSynchronize = true,
10381038
ClientId = clientId
10391039
};
1040-
NetworkManager.MessageManager.SendMessage(ref message, NetworkDelivery.ReliableSequenced, NetworkManager.CurrentSessionOwner);
1040+
NetworkManager.MessageManager.SendMessage(ref message, networkDelivery, NetworkManager.CurrentSessionOwner);
10411041
}
10421042
}
10431043
if (!ConnectedClientIds.Contains(clientId))
@@ -1286,7 +1286,7 @@ internal void OnClientDisconnectFromServer(ulong clientId)
12861286

12871287
ConnectedClientIds.Remove(clientId);
12881288
var message = new ClientDisconnectedMessage { ClientId = clientId };
1289-
MessageManager?.SendMessage(ref message, NetworkDelivery.ReliableFragmentedSequenced, ConnectedClientIds);
1289+
MessageManager?.SendMessage(ref message, MessageDelivery.GetDelivery(NetworkMessageTypes.ClientDisconnected), ConnectedClientIds);
12901290

12911291
// Used for testing/validation purposes only
12921292
#if ENABLE_DAHOST_AUTOPROMOTE_SESSION_OWNER

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ internal void __endSendServerRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
9999
{
100100
default:
101101
case RpcDelivery.Reliable:
102-
networkDelivery = NetworkDelivery.ReliableFragmentedSequenced;
102+
networkDelivery = MessageDelivery.GetDelivery(NetworkMessageTypes.ServerRpc);
103103
break;
104104
case RpcDelivery.Unreliable:
105105
if (bufferWriter.Length > networkManager.MessageManager.NonFragmentedMessageMaxSize)
@@ -180,7 +180,7 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
180180
{
181181
default:
182182
case RpcDelivery.Reliable:
183-
networkDelivery = NetworkDelivery.ReliableFragmentedSequenced;
183+
networkDelivery = MessageDelivery.GetDelivery(NetworkMessageTypes.ClientRpc);
184184
break;
185185
case RpcDelivery.Unreliable:
186186
if (bufferWriter.Length > networkManager.MessageManager.NonFragmentedMessageMaxSize)
@@ -344,14 +344,14 @@ internal void __endSendRpc(ref FastBufferWriter bufferWriter, uint rpcMethodId,
344344
{
345345
default:
346346
case RpcDelivery.Reliable:
347-
networkDelivery = NetworkDelivery.ReliableFragmentedSequenced;
347+
networkDelivery = MessageDelivery.GetDelivery(NetworkMessageTypes.Rpc);
348348
break;
349349
case RpcDelivery.Unreliable:
350350
if (bufferWriter.Length > NetworkManager.MessageManager.NonFragmentedMessageMaxSize)
351351
{
352352
throw new OverflowException("RPC parameters are too large for unreliable delivery.");
353353
}
354-
networkDelivery = NetworkDelivery.Unreliable;
354+
networkDelivery = NetworkDelivery.UnreliableSequenced;
355355
break;
356356
}
357357

@@ -1011,7 +1011,7 @@ internal void InitializeVariables()
10111011

10121012
for (int i = 0; i < NetworkVariableFields.Count; i++)
10131013
{
1014-
var networkDelivery = NetworkVariableBase.Delivery;
1014+
var networkDelivery = MessageDelivery.GetDelivery(NetworkMessageTypes.NetworkVariableDelta);
10151015
if (!firstLevelIndex.ContainsKey(networkDelivery))
10161016
{
10171017
firstLevelIndex.Add(networkDelivery, secondLevelCounter);

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ internal void AddForUpdate(NetworkObject networkObject)
2727
/// Sends NetworkVariable deltas
2828
/// </summary>
2929
/// <param name="forceSend">internal only, when changing ownership we want to send this before the change in ownership message</param>
30-
internal void NetworkBehaviourUpdate(bool forceSend = false)
30+
internal bool NetworkBehaviourUpdate(bool forceSend = false)
3131
{
3232
#if DEVELOPMENT_BUILD || UNITY_EDITOR
3333
m_NetworkBehaviourUpdate.Begin();
3434
#endif
35+
var sentMessages = false;
3536
try
3637
{
3738
foreach (var dirtyNetworkObject in m_PendingDirtyNetworkObjects)
@@ -62,6 +63,7 @@ internal void NetworkBehaviourUpdate(bool forceSend = false)
6263
for (int k = 0; k < dirtyObj.ChildNetworkBehaviours.Count; k++)
6364
{
6465
dirtyObj.ChildNetworkBehaviours[k].NetworkVariableUpdate(client.ClientId, forceSend);
66+
sentMessages = true;
6567
}
6668
}
6769
}
@@ -81,6 +83,7 @@ internal void NetworkBehaviourUpdate(bool forceSend = false)
8183
for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++)
8284
{
8385
sobj.ChildNetworkBehaviours[k].NetworkVariableUpdate(NetworkManager.ServerClientId, forceSend);
86+
sentMessages = true;
8487
}
8588
}
8689
}
@@ -124,6 +127,7 @@ internal void NetworkBehaviourUpdate(bool forceSend = false)
124127
m_NetworkBehaviourUpdate.End();
125128
#endif
126129
}
130+
return sentMessages;
127131
}
128132

129133
internal void Initialize(NetworkManager networkManager)
@@ -141,11 +145,12 @@ internal void Shutdown()
141145
// Order of operations requires NetworkVariable updates first then showing NetworkObjects
142146
private void NetworkBehaviourUpdater_Tick()
143147
{
144-
// First update NetworkVariables
145-
NetworkBehaviourUpdate();
146-
147-
// Then show any NetworkObjects queued to be made visible/shown
148-
m_NetworkManager.SpawnManager.HandleNetworkObjectShow();
148+
// Handle showing NetworkObjects on the next network tick
149+
if (NetworkBehaviourUpdate())
150+
{
151+
// Then show any NetworkObjects queued to be made visible/shown
152+
m_NetworkManager.SpawnManager.HandleNetworkObjectShow();
153+
}
149154

150155
// Handle object redistribution (DA + disabled scene management only)
151156
m_NetworkManager.HandleRedistributionToClients();

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ internal void PromoteSessionOwner(ulong clientId)
259259
var clients = ConnectionManager.ConnectedClientIds.Where(c => c != LocalClientId).ToArray();
260260
foreach (var targetClient in clients)
261261
{
262-
ConnectionManager.SendMessage(ref sessionOwnerMessage, NetworkDelivery.ReliableSequenced, targetClient);
262+
ConnectionManager.SendMessage(ref sessionOwnerMessage, MessageDelivery.GetDelivery(NetworkMessageTypes.SessionOwner), targetClient);
263263
}
264264
}
265265

@@ -439,6 +439,9 @@ public void NetworkUpdate(NetworkUpdateStage updateStage)
439439
SpawnManager.DeferredDespawnUpdate(ServerTime);
440440
}
441441

442+
// Send any pending objects to be shown (in-between ticks)
443+
SpawnManager.HandleNetworkObjectShow();
444+
442445
// Update any NetworkObject's registered to notify of scene migration changes.
443446
SpawnManager.UpdateNetworkObjectSceneChanges();
444447

0 commit comments

Comments
 (0)