-
-
Notifications
You must be signed in to change notification settings - Fork 206
Description
Unity version.
6000.0.66f1
Fish-Networking version.
4.6.20 Pro
Discord link where you troubleshot the issue.
https://discord.com/channels/424284635074134018/1034477094731784302/1469296146181656708
Description
NetworkTransform has issue in GetChanged method. It defines changed state on comparison of current transform state with _lastSentTransformData, including fields that are not Serialized. It leads to NetworkTransform constant streaming even if nothing actually changed.
Examples:
- If you have NetworkTransform with SynchronizePosition only and keep it static, it will send updates every tick because localScale of 1,1,1 will compare to _lastSentTransformData.Scale of 0,0,0
- If you have NetworkTransform with None synchronization, it will still send packets with metadata only either every tick how explained in example 1 or when transform state doesn't match of the whole default data of _lastSentTransformData.
Replication
Have any NetworkTransform on the scene with disabled Synchronize Scale
Launch server or server+client
Launch client.
Track on client for _networkTransform.OnDataReceived += DataReceivedHandler; - it will be equal to tick rate
On server, GetChange will return ChangedDelta.ScaleXYZ always.
Expected behavior
GetChanged method should check for respected properties only if they are set to serialize, otherwise it leads to assymetry in comparison between transform state and what actually sent
Supposed fix (adding if checks for properties) that fixed constant "dirtyness" for me (not sure about parent logic):
private ChangedDelta GetChanged(Vector3 lastPosition, Quaternion lastRotation, Vector3 lastScale, NetworkBehaviour lastParentBehaviour)
{
ChangedDelta changed = ChangedDelta.Unset;
Transform t = _cachedTransform;
if (_synchronizePosition)
{
Vector3 position = t.localPosition;
if (Mathf.Abs(position.x - lastPosition.x) >= _positionSensitivity)
changed |= ChangedDelta.PositionX;
if (Mathf.Abs(position.y - lastPosition.y) >= _positionSensitivity)
changed |= ChangedDelta.PositionY;
if (Mathf.Abs(position.z - lastPosition.z) >= _positionSensitivity)
changed |= ChangedDelta.PositionZ;
}
if (_synchronizeRotation)
{
Quaternion rotation = t.localRotation;
if (!rotation.Matches(lastRotation, true))
changed |= ChangedDelta.Rotation;
}
ChangedDelta startChanged = changed;
if (_synchronizeScale)
{
Vector3 scale = t.localScale;
if (Mathf.Abs(scale.x - lastScale.x) >= _scaleSensitivity)
changed |= ChangedDelta.ScaleX;
if (Mathf.Abs(scale.y - lastScale.y) >= _scaleSensitivity)
changed |= ChangedDelta.ScaleY;
if (Mathf.Abs(scale.z - lastScale.z) >= _scaleSensitivity)
changed |= ChangedDelta.ScaleZ;
}
if (_synchronizeParent)
{
if (changed != ChangedDelta.Unset && ParentBehaviour != null)
changed |= ChangedDelta.Nested;
}
//If added scale or childed then also add extended.
if (startChanged != changed)
changed |= ChangedDelta.Extended;
return changed;
}