fix: NetworkTransformUnreliable: timeStampAdjustment, timelineOffset to fix 2s jitter after tab switching in webgl caused by NT snaps potentially arriving behind timeline snaps (#3441)

* NT-U: Implemented sendIntervalMultiplier, timeStampAdjustment, timelineOffset

* Update Assets/Mirror/Components/NetworkTransformUnreliable/NetworkTransform.cs

Co-authored-by: mischa <16416509+vis2k@users.noreply.github.com>

---------

Co-authored-by: mischa <16416509+vis2k@users.noreply.github.com>
This commit is contained in:
MrGadget 2023-04-03 12:39:01 -04:00 committed by GitHub
parent ae40fcbddd
commit 12ebd7f722
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -36,6 +36,31 @@ public class NetworkTransform : NetworkTransformBase
double lastClientSendTime; double lastClientSendTime;
double lastServerSendTime; double lastServerSendTime;
[Header("Send Interval Multiplier")]
[Tooltip("Check/Sync every multiple of Network Manager send interval (= 1 / NM Send Rate), instead of every send interval.")]
[Range(1, 120)]
const uint sendIntervalMultiplier = 1; // not implemented yet
[Header("Snapshot Interpolation")]
[Tooltip("Add a small timeline offset to account for decoupled arrival of NetworkTime and NetworkTransform snapshots.\nfixes: https://github.com/MirrorNetworking/Mirror/issues/3427")]
public bool timelineOffset = false;
// Ninja's Notes on offset & mulitplier:
//
// In a no multiplier scenario:
// 1. Snapshots are sent every frame (frame being 1 NM send interval).
// 2. Time Interpolation is set to be 'behind' by 2 frames times.
// In theory where everything works, we probably have around 2 snapshots before we need to interpolate snapshots. From NT perspective, we should always have around 2 snapshots ready, so no stutter.
//
// In a multiplier scenario:
// 1. Snapshots are sent every 10 frames.
// 2. Time Interpolation remains 'behind by 2 frames'.
// When everything works, we are receiving NT snapshots every 10 frames, but start interpolating after 2.
// Even if I assume we had 2 snapshots to begin with to start interpolating (which we don't), by the time we reach 13th frame, we are out of snapshots, and have to wait 7 frames for next snapshot to come. This is the reason why we absolutely need the timestamp adjustment. We are starting way too early to interpolate.
//
double timeStampAdjustment => NetworkServer.sendInterval * (sendIntervalMultiplier - 1);
double offset => timelineOffset ? NetworkServer.sendInterval * sendIntervalMultiplier : 0;
// update ////////////////////////////////////////////////////////////// // update //////////////////////////////////////////////////////////////
// Update applies interpolation // Update applies interpolation
void Update() void Update()
@ -326,7 +351,7 @@ protected virtual void OnClientToServerSync(Vector3? position, Quaternion? rotat
} }
} }
#endif #endif
AddSnapshot(serverSnapshots, timestamp, position, rotation, scale); AddSnapshot(serverSnapshots, connectionToClient.remoteTimeStamp + timeStampAdjustment + offset, position, rotation, scale);
} }
// rpc ///////////////////////////////////////////////////////////////// // rpc /////////////////////////////////////////////////////////////////
@ -365,7 +390,7 @@ protected virtual void OnServerToClientSync(Vector3? position, Quaternion? rotat
} }
} }
#endif #endif
AddSnapshot(clientSnapshots, timestamp, position, rotation, scale); AddSnapshot(clientSnapshots, NetworkClient.connection.remoteTimeStamp + timeStampAdjustment + offset, position, rotation, scale);
} }
} }
} }