diff --git a/Assets/Mirror/Core/Messages.cs b/Assets/Mirror/Core/Messages.cs index 49ee25f17..978f39e5c 100644 --- a/Assets/Mirror/Core/Messages.cs +++ b/Assets/Mirror/Core/Messages.cs @@ -3,6 +3,14 @@ namespace Mirror { + // need to send time every sendInterval. + // batching automatically includes remoteTimestamp. + // all we need to do is ensure that an empty message is sent. + // and react to it. + // => we don't want to insert a snapshot on every batch. + // => do it exactly every sendInterval on every TimeSnapshotMessage. + public struct TimeSnapshotMessage : NetworkMessage {} + public struct ReadyMessage : NetworkMessage {} public struct NotReadyMessage : NetworkMessage {} diff --git a/Assets/Mirror/Core/NetworkClient.cs b/Assets/Mirror/Core/NetworkClient.cs index 17ffc9cd0..1584cb693 100644 --- a/Assets/Mirror/Core/NetworkClient.cs +++ b/Assets/Mirror/Core/NetworkClient.cs @@ -237,6 +237,7 @@ internal static void RegisterSystemHandlers(bool hostMode) } // These handlers are the same for host and remote clients + RegisterHandler(OnTimeSnapshotMessage); RegisterHandler(OnChangeOwner); RegisterHandler(OnRPCMessage); } diff --git a/Assets/Mirror/Core/NetworkClient_TimeInterpolation.cs b/Assets/Mirror/Core/NetworkClient_TimeInterpolation.cs index e70809a5f..79039ed41 100644 --- a/Assets/Mirror/Core/NetworkClient_TimeInterpolation.cs +++ b/Assets/Mirror/Core/NetworkClient_TimeInterpolation.cs @@ -60,11 +60,22 @@ static void InitTimeInterpolation() deliveryTimeEma = new ExponentialMovingAverage(NetworkServer.config.sendRate * config.deliveryTimeEmaDuration); } + // server sends TimeSnapshotMessage every sendInterval. + // batching already includes the remoteTimestamp. + // we simply insert it on-message here. + // => only for reliable channel. unreliable would always arrive earlier. + static void OnTimeSnapshotMessage(TimeSnapshotMessage _) + { + // insert another snapshot for snapshot interpolation. + // before calling OnDeserialize so components can use + // NetworkTime.time and NetworkTime.timeStamp. + OnTimeSnapshot(new TimeSnapshot(connection.remoteTimeStamp, Time.timeAsDouble)); + } + // see comments at the top of this file public static void OnTimeSnapshot(TimeSnapshot snap) { - // set local timestamp (= when it was received on our end) - snap.localTime = Time.timeAsDouble; + // Debug.Log($"NetworkClient: OnTimeSnapshot @ {snap.remoteTime:F3}"); // (optional) dynamic adjustment if (config.dynamicAdjustment) diff --git a/Assets/Mirror/Core/NetworkServer.cs b/Assets/Mirror/Core/NetworkServer.cs index 0a30df17b..cfa51983d 100644 --- a/Assets/Mirror/Core/NetworkServer.cs +++ b/Assets/Mirror/Core/NetworkServer.cs @@ -1704,6 +1704,10 @@ static void Broadcast() // pull in UpdateVarsMessage for each entity it observes if (connection.isReady) { + // send time for snapshot interpolation every sendInterval. + // BroadcastToConnection() may not send if nothing is new. + connection.Send(new TimeSnapshotMessage()); + // broadcast world state to this connection BroadcastToConnection(connection); }