mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 11:00:32 +00:00
Fixed V2 where full sync data is quantized first before considering delta
This causes premature rounding error (seen in tank turret bobbing) because full sync data has a rotation less than rotationSensitivity but non 0. but new snapshot derived from delta + quantized full sync data will produce a rotation of 0. WIP - Need to fix this in V1
This commit is contained in:
parent
65280a8f17
commit
04f247d43e
@ -20,7 +20,7 @@ public class HybridNetworkTransformV2 : NetworkBehaviour
|
||||
[Tooltip("Select the attributes to sync")]
|
||||
[SerializeField] protected SyncSettings syncSettings = SyncSettings.SyncPosX | SyncSettings.SyncPosY | SyncSettings.SyncPosZ | SyncSettings.SyncRot;
|
||||
protected FullHeader fullHeader;
|
||||
|
||||
|
||||
[Header("Rotation")]
|
||||
[Tooltip("Send Rotation data as uncompressed Quaternion, compressed Quaternion (smallest 3) or by Euler Angles")]
|
||||
[SerializeField] protected RotationSettings rotationSettings = RotationSettings.Compressed;
|
||||
@ -48,9 +48,9 @@ public class HybridNetworkTransformV2 : NetworkBehaviour
|
||||
double lastFullSendIntervalTime = double.MinValue;
|
||||
private byte lastSentFullSyncIndex = 0;
|
||||
private SyncDataFull lastSentFullSyncData;
|
||||
private QuantizedSnapshot lastSentFullQuantized;
|
||||
//private QuantizedSnapshot lastSentFullQuantized;
|
||||
private SyncDataFull lastReceivedFullSyncData;
|
||||
private QuantizedSnapshot lastReceivedFullQuantized;
|
||||
//private QuantizedSnapshot lastReceivedFullQuantized;
|
||||
|
||||
/*[Header("Delta Send Interval Multiplier")]
|
||||
[Tooltip("Check/Sync every multiple of Network Manager send interval (= 1 / NM Send Rate), instead of every send interval.\n(30 NM send rate, and 3 interval, is a send every 0.1 seconds)\nA larger interval means less network sends, which has a variety of upsides. The drawbacks are delays and lower accuracy, you should find a nice balance between not sending too much, but the results looking good for your particular scenario.")]
|
||||
@ -271,7 +271,7 @@ public override void OnSerialize(NetworkWriter writer, bool initialState)
|
||||
if (syncRotation) writer.WriteQuaternion(lastSentFullSyncData.rotation);
|
||||
if (syncScale) writer.WriteVector3(lastSentFullSyncData.scale);
|
||||
|
||||
lastSentFullQuantized = ConstructQuantizedSnapshot(lastSentFullSyncData.position, lastSentFullSyncData.rotation, lastSentFullSyncData.scale);
|
||||
//lastSentFullQuantized = ConstructQuantizedSnapshot(lastSentFullSyncData.position, lastSentFullSyncData.rotation, lastSentFullSyncData.scale);
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,7 +400,7 @@ protected virtual void ServerBroadcastFull()
|
||||
{
|
||||
lastSentFullSyncData = ConstructFullSyncData(true);
|
||||
|
||||
lastSentFullQuantized = ConstructQuantizedSnapshot(lastSentFullSyncData.position, lastSentFullSyncData.rotation, lastSentFullSyncData.scale);
|
||||
//lastSentFullQuantized = ConstructQuantizedSnapshot(lastSentFullSyncData.position, lastSentFullSyncData.rotation, lastSentFullSyncData.scale);
|
||||
|
||||
SyncDataFullMsg msg = new SyncDataFullMsg(netId, ComponentIndex, lastSentFullSyncData);
|
||||
SendToReadyObservers(netIdentity, msg, false, Channels.Reliable); // will exclude owner be problematic?
|
||||
@ -442,7 +442,7 @@ public virtual void OnServerToClientSyncFull(SyncDataFull syncData)
|
||||
// use current non-synced axis instead of giving it a 0.
|
||||
lastReceivedFullSyncData = syncData;
|
||||
CleanUpFullSyncDataPositionSync(ref lastReceivedFullSyncData);
|
||||
lastReceivedFullQuantized = ConstructQuantizedSnapshot(lastReceivedFullSyncData.position, lastReceivedFullSyncData.rotation, lastReceivedFullSyncData.scale);
|
||||
//lastReceivedFullQuantized = ConstructQuantizedSnapshot(lastReceivedFullSyncData.position, lastReceivedFullSyncData.rotation, lastReceivedFullSyncData.scale);
|
||||
|
||||
// We don't care if we are adding 'default' to any field because
|
||||
// syncing is checked again in Apply before applying the changes.
|
||||
@ -458,9 +458,9 @@ protected virtual void ServerBroadcastDelta()
|
||||
|
||||
if (lastSentFullSyncIndex == 0) return;
|
||||
SyncDataFull currentFull = ConstructFullSyncData(false);
|
||||
QuantizedSnapshot currentQuantized = ConstructQuantizedSnapshot(currentFull.position, currentFull.rotation, currentFull.scale);
|
||||
//QuantizedSnapshot currentQuantized = ConstructQuantizedSnapshot(currentFull.position, currentFull.rotation, currentFull.scale);
|
||||
|
||||
SyncDataDelta syncDataDelta = DeriveDelta(currentQuantized);
|
||||
SyncDataDelta syncDataDelta = DeriveDelta(currentFull);
|
||||
|
||||
SyncDataDeltaMsg msg = new SyncDataDeltaMsg(netId, ComponentIndex, syncDataDelta);
|
||||
SendToReadyObservers(netIdentity, msg, false, Channels.Unreliable); // will exclude owner be problematic?
|
||||
@ -509,8 +509,13 @@ protected virtual void ClientBroadcastFull()
|
||||
{
|
||||
lastSentFullSyncData = ConstructFullSyncData(true);
|
||||
|
||||
lastSentFullQuantized = ConstructQuantizedSnapshot(lastSentFullSyncData.position, lastSentFullSyncData.rotation, lastSentFullSyncData.scale);
|
||||
|
||||
//lastSentFullQuantized = ConstructQuantizedSnapshot(lastSentFullSyncData.position, lastSentFullSyncData.rotation, lastSentFullSyncData.scale);
|
||||
|
||||
/*if (gameObject.name.Contains("Turret"))
|
||||
{
|
||||
Debug.Log($"Pos Y = {lastSentFullSyncData.position.y.ToString("F10")}");
|
||||
Debug.Log($"Pos Y Quantized = {lastSentFullQuantized.position.y}");
|
||||
}*/
|
||||
SyncDataFullMsg msg = new SyncDataFullMsg(netId, ComponentIndex, lastSentFullSyncData);
|
||||
NetworkClient.Send(msg, Channels.Reliable);
|
||||
}
|
||||
@ -549,8 +554,9 @@ protected virtual void OnClientToServerSyncFull(SyncDataFull syncData)
|
||||
|
||||
// See Server's issue
|
||||
lastReceivedFullSyncData = syncData;
|
||||
if (gameObject.name.Contains("Turret")) Debug.Log($"Pos Y Received = {lastReceivedFullSyncData.position.y.ToString("F10")}");
|
||||
CleanUpFullSyncDataPositionSync(ref lastReceivedFullSyncData);
|
||||
lastReceivedFullQuantized = ConstructQuantizedSnapshot(lastReceivedFullSyncData.position, lastReceivedFullSyncData.rotation, lastReceivedFullSyncData.scale);
|
||||
//lastReceivedFullQuantized = ConstructQuantizedSnapshot(lastReceivedFullSyncData.position, lastReceivedFullSyncData.rotation, lastReceivedFullSyncData.scale);
|
||||
|
||||
// We don't care if we are adding 'default' to any field because
|
||||
// syncing is checked again in Apply before applying the changes.
|
||||
@ -565,9 +571,10 @@ protected virtual void ClientBroadcastDelta()
|
||||
if (lastSentFullSyncIndex == 0) return;
|
||||
|
||||
SyncDataFull currentFull = ConstructFullSyncData(false);
|
||||
QuantizedSnapshot currentQuantized = ConstructQuantizedSnapshot(currentFull.position, currentFull.rotation, currentFull.scale);
|
||||
|
||||
SyncDataDelta syncDataDelta = DeriveDelta(currentQuantized);
|
||||
//QuantizedSnapshot currentQuantized = ConstructQuantizedSnapshot(currentFull.position, currentFull.rotation, currentFull.scale);
|
||||
|
||||
SyncDataDelta syncDataDelta = DeriveDelta(currentFull);
|
||||
if (gameObject.name.Contains("Turret")) Debug.Log($"Pos Y Delta = {syncDataDelta.position.y}");
|
||||
|
||||
SyncDataDeltaMsg msg = new SyncDataDeltaMsg(netId, ComponentIndex, syncDataDelta);
|
||||
NetworkClient.Send(msg, Channels.Unreliable);
|
||||
@ -638,13 +645,13 @@ protected virtual QuantizedSnapshot ConstructQuantizedSnapshot(Vector3 position,
|
||||
);
|
||||
}
|
||||
|
||||
protected virtual SyncDataDelta DeriveDelta(QuantizedSnapshot current)
|
||||
protected virtual SyncDataDelta DeriveDelta(SyncDataFull current)
|
||||
{
|
||||
SyncDataDelta syncDataDelta = new SyncDataDelta();
|
||||
syncDataDelta.fullSyncDataIndex = lastSentFullSyncIndex;
|
||||
syncDataDelta.deltaHeader = DeltaHeader.None;
|
||||
|
||||
syncDataDelta.position = current.position - lastSentFullQuantized.position;
|
||||
Compression.ScaleToLong(current.position - lastSentFullSyncData.position, positionPrecision, out syncDataDelta.position);
|
||||
|
||||
if ((fullHeader & FullHeader.SyncPosX) > 0 && syncDataDelta.position.x != 0)
|
||||
syncDataDelta.deltaHeader |= DeltaHeader.PosX;
|
||||
@ -674,7 +681,7 @@ protected virtual SyncDataDelta DeriveDelta(QuantizedSnapshot current)
|
||||
{
|
||||
if ((fullHeader & FullHeader.UseEulerAngles) > 0)
|
||||
{
|
||||
Compression.ScaleToLong(lastSentFullQuantized.rotation.eulerAngles, rotationSensitivity, out Vector3Long lastRotationEuler);
|
||||
Compression.ScaleToLong(lastSentFullSyncData.rotation.eulerAngles, rotationSensitivity, out Vector3Long lastRotationEuler);
|
||||
Compression.ScaleToLong(current.rotation.eulerAngles, rotationSensitivity, out Vector3Long currentRotationEuler);
|
||||
|
||||
syncDataDelta.eulRotation = currentRotationEuler - lastRotationEuler;
|
||||
@ -685,7 +692,7 @@ protected virtual SyncDataDelta DeriveDelta(QuantizedSnapshot current)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Quaternion.Angle(lastSentFullQuantized.rotation, current.rotation) > rotationSensitivity)
|
||||
if (Quaternion.Angle(lastSentFullSyncData.rotation, current.rotation) > rotationSensitivity)
|
||||
{
|
||||
syncDataDelta.quatRotation = current.rotation;
|
||||
syncDataDelta.deltaHeader |= DeltaHeader.SendQuat;
|
||||
@ -699,7 +706,7 @@ protected virtual SyncDataDelta DeriveDelta(QuantizedSnapshot current)
|
||||
|
||||
if ((fullHeader & FullHeader.SyncScale) > 0)
|
||||
{
|
||||
syncDataDelta.scale = current.scale - lastSentFullQuantized.scale;
|
||||
Compression.ScaleToLong(current.scale - lastSentFullSyncData.scale, positionPrecision, out syncDataDelta.scale);
|
||||
if (syncDataDelta.scale != Vector3Long.zero)
|
||||
{
|
||||
syncDataDelta.deltaHeader |= DeltaHeader.Scale;
|
||||
@ -711,11 +718,11 @@ protected virtual SyncDataDelta DeriveDelta(QuantizedSnapshot current)
|
||||
|
||||
protected virtual void ApplyDelta(SyncDataDelta delta, out Vector3 position, out Quaternion rotation, out Vector3 scale)
|
||||
{
|
||||
position = Compression.ScaleToFloat(lastReceivedFullQuantized.position + delta.position, positionPrecision);
|
||||
position = lastReceivedFullSyncData.position + Compression.ScaleToFloat(delta.position, positionPrecision);
|
||||
|
||||
if ((lastReceivedFullSyncData.fullHeader & FullHeader.UseEulerAngles) > 0)
|
||||
{
|
||||
Vector3 eulRotation = Compression.ScaleToFloat(lastReceivedFullQuantized.rotationEuler + delta.eulRotation, rotationSensitivity);
|
||||
Vector3 eulRotation = lastReceivedFullSyncData.rotation.eulerAngles + Compression.ScaleToFloat(delta.eulRotation, rotationSensitivity);
|
||||
|
||||
rotation = Quaternion.Euler(eulRotation);
|
||||
}
|
||||
@ -727,7 +734,7 @@ protected virtual void ApplyDelta(SyncDataDelta delta, out Vector3 position, out
|
||||
rotation = lastReceivedFullSyncData.rotation;
|
||||
}
|
||||
|
||||
scale = Compression.ScaleToFloat(lastReceivedFullQuantized.scale + delta.scale, scalePrecision);
|
||||
scale = lastReceivedFullSyncData.scale + Compression.ScaleToFloat(delta.scale, scalePrecision);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user