mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
fix: serialization precision over days by using frameCount instead of single precision time (#2815)
* fix: serialization precision over days by saving a double timestamp at the start of Broadcast() once * use tick instead
This commit is contained in:
parent
9ac3cf9534
commit
188be9ead0
@ -24,7 +24,8 @@ public enum Visibility { Default, ForceHidden, ForceShown }
|
|||||||
|
|
||||||
public struct NetworkIdentitySerialization
|
public struct NetworkIdentitySerialization
|
||||||
{
|
{
|
||||||
public float tickTimeStamp;
|
// IMPORTANT: int tick avoids floating point inaccuracy over days/weeks
|
||||||
|
public int tick;
|
||||||
public NetworkWriter ownerWriter;
|
public NetworkWriter ownerWriter;
|
||||||
public NetworkWriter observersWriter;
|
public NetworkWriter observersWriter;
|
||||||
// TODO there is probably a more simple way later
|
// TODO there is probably a more simple way later
|
||||||
@ -940,11 +941,12 @@ internal void OnSerializeAllSafely(bool initialState, NetworkWriter ownerWriter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get cached serialization for this tick (or serialize if none yet)
|
// get cached serialization for this tick (or serialize if none yet)
|
||||||
// IMPORTANT: needs FRAME TIME which doesn't change during THIS FRAME!
|
// IMPORTANT: int tick avoids floating point inaccuracy over days/weeks
|
||||||
internal NetworkIdentitySerialization GetSerializationAtTick(float tickTimeStamp)
|
internal NetworkIdentitySerialization GetSerializationAtTick(int tick)
|
||||||
{
|
{
|
||||||
// serialize fresh if tick is newer than last one
|
// reserialize if tick is different than last changed.
|
||||||
if (lastSerialization.tickTimeStamp < tickTimeStamp)
|
// NOTE: != instead of < because int.max+1 overflows at some point.
|
||||||
|
if (lastSerialization.tick != tick)
|
||||||
{
|
{
|
||||||
// reset
|
// reset
|
||||||
lastSerialization.ownerWriter.Position = 0;
|
lastSerialization.ownerWriter.Position = 0;
|
||||||
@ -957,8 +959,8 @@ internal NetworkIdentitySerialization GetSerializationAtTick(float tickTimeStamp
|
|||||||
lastSerialization.observersWriter,
|
lastSerialization.observersWriter,
|
||||||
out lastSerialization.observersWritten);
|
out lastSerialization.observersWritten);
|
||||||
|
|
||||||
// set timestamp
|
// set tick
|
||||||
lastSerialization.tickTimeStamp = tickTimeStamp;
|
lastSerialization.tick = tick;
|
||||||
//Debug.Log($"{name} (netId={netId}) serialized for tick={tickTimeStamp}");
|
//Debug.Log($"{name} (netId={netId}) serialized for tick={tickTimeStamp}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1432,8 +1432,8 @@ public static void RebuildObservers(NetworkIdentity identity, bool initialize)
|
|||||||
static NetworkWriter GetEntitySerializationForConnection(NetworkIdentity identity, NetworkConnectionToClient connection)
|
static NetworkWriter GetEntitySerializationForConnection(NetworkIdentity identity, NetworkConnectionToClient connection)
|
||||||
{
|
{
|
||||||
// get serialization for this entity (cached)
|
// get serialization for this entity (cached)
|
||||||
// IMPORTANT: needs FRAME TIME which doesn't change during THIS FRAME!
|
// IMPORTANT: int tick avoids floating point inaccuracy over days/weeks
|
||||||
NetworkIdentitySerialization serialization = identity.GetSerializationAtTick(Time.time);
|
NetworkIdentitySerialization serialization = identity.GetSerializationAtTick(Time.frameCount);
|
||||||
|
|
||||||
// is this entity owned by this connection?
|
// is this entity owned by this connection?
|
||||||
bool owned = identity.connectionToClient == connection;
|
bool owned = identity.connectionToClient == connection;
|
||||||
|
@ -64,14 +64,15 @@ public IEnumerator OnDestroyIsServerTrueWhenNetworkServerDestroyIsCalled()
|
|||||||
public IEnumerator TestSerializationWithLargeTimestamps()
|
public IEnumerator TestSerializationWithLargeTimestamps()
|
||||||
{
|
{
|
||||||
// 14 * 24 hours per day * 60 minutes per hour * 60 seconds per minute = 14 days
|
// 14 * 24 hours per day * 60 minutes per hour * 60 seconds per minute = 14 days
|
||||||
float time = 14 * 24 * 60 * 60;
|
// NOTE: change this to 'float' to see the tests fail
|
||||||
NetworkIdentitySerialization serialization = identity.GetSerializationAtTick(time);
|
int tick = 14 * 24 * 60 * 60;
|
||||||
// advance time by 50ms (20 fps)
|
NetworkIdentitySerialization serialization = identity.GetSerializationAtTick(tick);
|
||||||
time += 0.05f;
|
// advance tick
|
||||||
NetworkIdentitySerialization serializationNew = identity.GetSerializationAtTick(time);
|
++tick;
|
||||||
|
NetworkIdentitySerialization serializationNew = identity.GetSerializationAtTick(tick);
|
||||||
|
|
||||||
// if the serialization has been changed the tickTimeStamp should have moved
|
// if the serialization has been changed the tickTimeStamp should have moved
|
||||||
Assert.That(serialization.tickTimeStamp == serializationNew.tickTimeStamp, Is.False);
|
Assert.That(serialization.tick == serializationNew.tick, Is.False);
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user