Skip to content

Commit 0a57b18

Browse files
update
Some touch ups and adjustments to the fix for the extrapolation issue.
1 parent 9acf82d commit 0a57b18

File tree

1 file changed

+67
-57
lines changed

1 file changed

+67
-57
lines changed

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

Lines changed: 67 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,6 @@ public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReade
391391
private readonly NetworkVariable<NetworkTransformState> m_ReplicatedNetworkStateServer = new NetworkVariable<NetworkTransformState>(new NetworkTransformState(), NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
392392
private readonly NetworkVariable<NetworkTransformState> m_ReplicatedNetworkStateOwner = new NetworkVariable<NetworkTransformState>(new NetworkTransformState(), NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner);
393393

394-
395394
internal NetworkVariable<NetworkTransformState> ReplicatedNetworkState
396395
{
397396
get
@@ -405,10 +404,6 @@ internal NetworkVariable<NetworkTransformState> ReplicatedNetworkState
405404
}
406405
}
407406

408-
private NetworkTransformState m_LocalAuthoritativeNetworkState;
409-
410-
private bool m_HasSentLastValue = false; // used to send one last value, so clients can make the difference between lost replication data (clients extrapolate) and no more data to send.
411-
412407
private ClientRpcParams m_ClientRpcParams = new ClientRpcParams() { Send = new ClientRpcSendParams() };
413408
private List<ulong> m_ClientIds = new List<ulong>() { 0 };
414409

@@ -421,12 +416,25 @@ internal NetworkVariable<NetworkTransformState> ReplicatedNetworkState
421416
private BufferedLinearInterpolator<float> m_ScaleZInterpolator;
422417
private readonly List<BufferedLinearInterpolator<float>> m_AllFloatInterpolators = new List<BufferedLinearInterpolator<float>>(6);
423418

424-
private int m_LastSentTick;
419+
// Used by both authoritative and non-authoritative instances.
420+
// This represents the most recent local authoritative state.
421+
private NetworkTransformState m_LocalAuthoritativeNetworkState;
422+
423+
// Used by integration test
425424
private NetworkTransformState m_LastSentState;
426425

427-
// Used by the non-authoritative side to handle ending extrapolation (replaces server sending)
426+
// Used by the non-authoritative side to handle ending extrapolation
428427
private NetworkTransformState m_LastReceivedState;
429428

429+
/// Calculated when spawned, this is used to offset a newly received non-authority side state by 1 tick duration
430+
/// in order to end the extrapolation for that state's values.
431+
/// Example:
432+
/// NetworkState-A is received, processed, and measurements added
433+
/// NetworkState-A is duplicated (NetworkState-A-Post) and its sent time is offset by the tick frequency
434+
/// One tick later, NetworkState-A-Post is applied to end that delta's extrapolation.
435+
/// <see cref="OnNetworkStateChanged"/> to see how NetworkState-A-Post doesn't get excluded/missed
436+
private double m_TickFrequency;
437+
430438
internal NetworkTransformState GetLastSentState()
431439
{
432440
return m_LastSentState;
@@ -449,19 +457,8 @@ protected void TryCommitTransformToServer(Transform transformToCommit, double di
449457
return;
450458
}
451459

452-
/// If authority is invoking this, then treat it like we do with <see cref="Update"/>
453-
if (CanCommitToTransform)
454-
{
455-
// If our replicated state is not dirty and our local authority state is dirty, clear it.
456-
if (!ReplicatedNetworkState.IsDirty() && m_LocalAuthoritativeNetworkState.IsDirty)
457-
{
458-
// Now clear our bitset and prepare for next network tick state update
459-
m_LocalAuthoritativeNetworkState.ClearBitSetForNextTick();
460-
}
461-
462-
TryCommitTransform(transformToCommit, m_CachedNetworkManager.LocalTime.Time);
463-
}
464-
else
460+
// Either updates the authority or sends and RPC to the authoritative instance
461+
if (!TryUpdateAuthority(transformToCommit))
465462
{
466463
// We are an owner requesting to update our state
467464
if (!m_CachedIsServer)
@@ -488,9 +485,10 @@ private void TryCommitTransform(Transform transformToCommit, double dirtyTime)
488485
return;
489486
}
490487

488+
// If the transform has deltas (returns dirty) then...
491489
if (ApplyTransformToNetworkState(ref m_LocalAuthoritativeNetworkState, dirtyTime, transformToCommit))
492490
{
493-
// Commit the state
491+
// ...commit the state
494492
ReplicatedNetworkState.Value = m_LocalAuthoritativeNetworkState;
495493
}
496494
}
@@ -765,12 +763,6 @@ private void ApplyAuthoritativeState()
765763
}
766764
}
767765

768-
[ServerRpc]
769-
private void UpdateServerWithAppliedRotationServerRpc(Vector3 eulerAngles)
770-
{
771-
Debug.Log($"[{name}] client updated their rotation to ({eulerAngles})");
772-
}
773-
774766
/// <summary>
775767
/// Only non-authoritative instances should invoke this
776768
/// </summary>
@@ -924,27 +916,24 @@ private void AddInterpolatedState(NetworkTransformState newState)
924916
}
925917

926918
currentRotation.eulerAngles = currentEulerAngles;
927-
if (!IsServer && IsOwner)
928-
{
929-
UpdateServerWithUpdatedRotationServerRpc(currentEulerAngles);
930-
}
919+
931920
m_RotationInterpolator.AddMeasurement(currentRotation, sentTime);
932921
}
933922
}
934923

935-
[ServerRpc]
936-
private void UpdateServerWithUpdatedRotationServerRpc(Vector3 eulerAngles)
937-
{
938-
Debug.Log($"[{name}] Client notified it updated rotation interpolator with ({eulerAngles})");
939-
}
940-
941-
private void ApplyLastState()
924+
/// <summary>
925+
/// Stops extrapolating the <see cref="m_LastReceivedState"/>.
926+
/// </summary>
927+
/// <remarks>
928+
/// <see cref="OnNetworkStateChanged"/>
929+
/// </remarks>
930+
private void StopExtrapolatingLastState()
942931
{
943932
if (!m_LastReceivedState.IsDirty || m_LastReceivedState.ExtrapolateTick >= NetworkManager.LocalTime.Tick)
944933
{
945934
return;
946935
}
947-
m_LastReceivedState.SentTime += 1.0 / NetworkManager.NetworkConfig.TickRate;
936+
m_LastReceivedState.SentTime += m_TickFrequency;
948937
AddInterpolatedState(m_LastReceivedState);
949938
m_LastReceivedState.ClearBitSetForNextTick();
950939
}
@@ -967,7 +956,9 @@ private void OnNetworkStateChanged(NetworkTransformState oldState, NetworkTransf
967956

968957
if (Interpolate)
969958
{
970-
ApplyLastState();
959+
// This is "just in case" we receive a new state before the end
960+
// of any currently applied and potentially extrapolating state.
961+
StopExtrapolatingLastState();
971962
AddInterpolatedState(newState);
972963
m_LastReceivedState = newState;
973964
m_LastReceivedState.ExtrapolateTick = NetworkManager.LocalTime.Tick;
@@ -1020,6 +1011,7 @@ public override void OnNetworkSpawn()
10201011
{
10211012
m_CachedIsServer = IsServer;
10221013
m_CachedNetworkManager = NetworkManager;
1014+
m_TickFrequency = 1.0 / NetworkManager.NetworkConfig.TickRate;
10231015

10241016
Initialize();
10251017

@@ -1201,8 +1193,31 @@ private void SetStateServerRpc(Vector3 pos, Quaternion rot, Vector3 scale, bool
12011193
TryCommitTransform(transform, m_CachedNetworkManager.LocalTime.Time);
12021194
}
12031195

1204-
// todo: this is currently in update, to be able to catch any transform changes. A FixedUpdate mode could be added to be less intense, but it'd be
1205-
// conditional to users only making transform update changes in FixedUpdate.
1196+
/// <summary>
1197+
/// If the instance is authority it will attempt to update the current tick
1198+
/// network state and returns true.
1199+
/// If it is not authority it exits early returning false.
1200+
/// </summary>
1201+
/// <param name="transformSource">transform to be updated</param>
1202+
private bool TryUpdateAuthority(Transform transformSource)
1203+
{
1204+
if (!CanCommitToTransform)
1205+
{
1206+
return false;
1207+
}
1208+
1209+
// If our replicated state is not dirty and our local authority state is dirty, clear it.
1210+
if (!ReplicatedNetworkState.IsDirty() && m_LocalAuthoritativeNetworkState.IsDirty)
1211+
{
1212+
m_LastSentState = m_LocalAuthoritativeNetworkState;
1213+
// Now clear our bitset and prepare for next network tick state update
1214+
m_LocalAuthoritativeNetworkState.ClearBitSetForNextTick();
1215+
}
1216+
1217+
TryCommitTransform(transformSource, m_CachedNetworkManager.LocalTime.Time);
1218+
return true;
1219+
}
1220+
12061221
/// <inheritdoc/>
12071222
/// <remarks>
12081223
/// If you override this method, be sure that:
@@ -1217,21 +1232,14 @@ protected virtual void Update()
12171232
return;
12181233
}
12191234

1220-
if (CanCommitToTransform)
1221-
{
1222-
// If our replicated state is not dirty and our local authority state is dirty, clear it.
1223-
if (!ReplicatedNetworkState.IsDirty() && m_LocalAuthoritativeNetworkState.IsDirty)
1224-
{
1225-
// Now clear our bitset and prepare for next network tick state update
1226-
m_LocalAuthoritativeNetworkState.ClearBitSetForNextTick();
1227-
}
1228-
TryCommitTransform(transform, m_CachedNetworkManager.LocalTime.Time);
1229-
}
1230-
else
1235+
// Either updates the authority or handle:
1236+
// - Non-authoritative side interpolation
1237+
// - Applying the current authoritative state
1238+
// - Stop extrapolating the current state (if it is 1 tick after it was received)
1239+
if (!TryUpdateAuthority(transform))
12311240
{
12321241
if (Interpolate)
12331242
{
1234-
// eventually, we could hoist this calculation so that it happens once for all objects, not once per object
12351243
var serverTime = NetworkManager.ServerTime;
12361244
var cachedDeltaTime = Time.deltaTime;
12371245
var cachedServerTime = serverTime.Time;
@@ -1243,11 +1251,13 @@ protected virtual void Update()
12431251

12441252
m_RotationInterpolator.Update(cachedDeltaTime, cachedRenderTime, cachedServerTime);
12451253
}
1246-
// Now apply the current authoritative state
1247-
ApplyAuthoritativeState();
12481254

1255+
// Apply the current authoritative state
1256+
ApplyAuthoritativeState();
12491257

1250-
ApplyLastState();
1258+
// Handles stopping extrapolation for any previously
1259+
// applied state.
1260+
StopExtrapolatingLastState();
12511261
}
12521262
}
12531263

0 commit comments

Comments
 (0)