Skip to content

Commit 7ba2a9d

Browse files
author
FirstGearGames
committed
4.6.20R
- Fixed NetworkObject.GraphicalObject smoother not working as clientOnly. - Fixed replicates from clients not running on server when using Inserted prediction order. - Fixed TimeManager simulates calling SyncTransforms on Physics2D rather than Physics2D.Simulate. - Added NetworkTickSmoother.FavorPredictionNetworkTransform. As true this disables smoothing when the NetworkObject enables prediction, specifies a NetworkTransform to use, and that NetworkTransform is currently smoothing. - Fixed tick smoothers interferring with NetworkTransform when EnableStateForwarding was disabled. - Fixed Prediction.Rigidbody demo creating reconcile in OnTick rather than OnPostTick.
1 parent e005324 commit 7ba2a9d

14 files changed

Lines changed: 253 additions & 176 deletions

File tree

Assets/FishNet/Demos/Prediction/CharacterController/Scripts/CharacterControllerPrediction.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,8 @@ private void CharacterTrigger_OnEnter(Collider c)
446446
/// </summary>
447447
private void CharacterTrigger_OnExit(Collider c)
448448
{
449+
if (c == null)
450+
return;
449451
if (!c.TryGetComponent(out MovingPlatform mp))
450452
return;
451453

Assets/FishNet/Demos/Prediction/Rigidbody/Scripts/RigidbodyPrediction.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ public override void OnStartNetwork()
139139
protected override void TimeManager_OnTick()
140140
{
141141
PerformReplicate(BuildMoveData());
142+
}
143+
144+
protected override void TimeManager_OnPostTick()
145+
{
142146
CreateReconcile();
143147
}
144148

Assets/FishNet/Runtime/Generated/Component/NetworkTransform/NetworkTransform.cs

Lines changed: 114 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ public enum ExtrapolateState : byte
283283
public TransformData() { }
284284

285285
internal void SetIsDefaultToFalse() => IsDefault = false;
286-
286+
287287
internal void Update(TransformData copy)
288288
{
289289
Update(copy.Tick, copy.Position, copy.Rotation, copy.Scale, copy.ExtrapolatedPosition, copy.ParentBehaviour);
@@ -646,9 +646,8 @@ public void SetSendToOwner(bool value)
646646
/// </summary>
647647
private TimeManager _timeManager;
648648
#endregion
649-
649+
650650
#region Private Profiler Markers
651-
652651
private static readonly ProfilerMarker _pm_OnUpdate = new("NetworkTransform.TimeManager_OnUpdate()");
653652
private static readonly ProfilerMarker _pm_OnPostTick = new("NetworkTransform.TimeManager_OnPostTick()");
654653
private static readonly ProfilerMarker _pm_MoveToTarget = new("NetworkTransform.MoveToTarget(float)");
@@ -657,7 +656,6 @@ public void SetSendToOwner(bool value)
657656
private static readonly ProfilerMarker _pm_ForceSend1 = new("NetworkTransform.ForceSend(uint)");
658657
private static readonly ProfilerMarker _pm_SendToClients = new("NetworkTransform.SendToClients()");
659658
private static readonly ProfilerMarker _pm_SendToServer = new("NetworkTransform.SendToServer(TransformData)");
660-
661659
#endregion
662660

663661
#region Const.
@@ -779,7 +777,6 @@ private void TryClearGoalDatas_OwnershipChange(NetworkConnection prevOwner, bool
779777
* follow the queue. */
780778
}
781779

782-
783780
private void TimeManager_OnUpdate()
784781
{
785782
using (_pm_OnUpdate.Auto())
@@ -859,13 +856,13 @@ private void ConfigureComponents()
859856
_initializedRigidbodyInterpolation2d = c.interpolation;
860857

861858
bool isKinematic = CanMakeKinematic();
862-
859+
863860
#if UNITY_6000_1_OR_NEWER
864861
c.bodyType = isKinematic ? RigidbodyType2D.Kinematic : RigidbodyType2D.Dynamic;
865862
#else
866863
c.isKinematic = isKinematic;
867864
#endif
868-
865+
869866
c.simulated = !isKinematic;
870867

871868
if (isKinematic)
@@ -1216,7 +1213,7 @@ private void SerializeChanged(ChangedDelta changed, PooledWriter writer, Transfo
12161213
//Compressed axis value.
12171214
float compressed;
12181215
//Multiplier for compression.
1219-
float multiplier = 100f;
1216+
float multiplier = 100f;
12201217
/* Maximum value compressed may be
12211218
* to send as compressed. */
12221219
float maxValue = short.MaxValue - 1;
@@ -1620,119 +1617,131 @@ private void MoveToTarget(float delta)
16201617
{
16211618
using (_pm_MoveToTarget.Auto())
16221619
{
1623-
if (_currentGoalData == null)
1624-
return;
1625-
1626-
//Cannot move if neither is active.
1627-
if (!IsServerInitialized && !IsClientInitialized)
1628-
return;
1620+
if (_currentGoalData == null)
1621+
return;
16291622

1630-
//If client auth and the owner don't move towards target.
1631-
if (_clientAuthoritative)
1632-
{
1633-
if (IsOwner || TakenOwnership)
1623+
//Cannot move if neither is active.
1624+
if (!IsServerInitialized && !IsClientInitialized)
16341625
return;
1635-
}
1636-
else
1637-
{
1638-
//If not client authoritative, is owner, and don't sync to owner.
1639-
if (IsOwner && !_sendToOwner)
1626+
1627+
if (!DoSettingsAllowSmoothing())
16401628
return;
1641-
}
16421629

1643-
//True if not client controlled.
1644-
bool controlledByClient = _clientAuthoritative && Owner.IsActive;
1645-
//If not controlled by client and is server then no reason to move.
1646-
if (!controlledByClient && IsServerInitialized)
1647-
return;
1630+
/* Once here it's safe to assume the object will be moving.
1631+
* Any checks which would stop it from moving be it client
1632+
* auth and owner, or server controlled and server, ect,
1633+
* would have already been run. */
1634+
TransformData td = _currentGoalData.Transforms;
1635+
RateData rd = _currentGoalData.Rates;
1636+
1637+
//Set parent.
1638+
if (_synchronizeParent)
1639+
SetParent(td.ParentBehaviour, rd);
1640+
1641+
float multiplier = 1f;
1642+
int queueCount = _goalDataQueue.Count;
1643+
//Increase move rate slightly if over queue count.
1644+
if (queueCount > _interpolation + 1)
1645+
multiplier += 0.05f;
1646+
1647+
//Rate to update. Changes per property.
1648+
float rate;
1649+
Transform t = _cachedTransform;
16481650

1649-
/* Once here it's safe to assume the object will be moving.
1650-
* Any checks which would stop it from moving be it client
1651-
* auth and owner, or server controlled and server, ect,
1652-
* would have already been run. */
1653-
TransformData td = _currentGoalData.Transforms;
1654-
RateData rd = _currentGoalData.Rates;
1651+
//Snap any bits of the transform that should be.
1652+
SnapProperties(td);
16551653

1656-
//Set parent.
1657-
if (_synchronizeParent)
1658-
SetParent(td.ParentBehaviour, rd);
1654+
//Position.
1655+
if (_synchronizePosition)
1656+
{
1657+
rate = rd.Position;
1658+
Vector3 posGoal = td.ExtrapolationState == TransformData.ExtrapolateState.Active && !_lastReceiveReliable ? td.ExtrapolatedPosition : td.Position;
1659+
// ReSharper disable once CompareOfFloatsByEqualityOperator
1660+
if (rate == -1f)
1661+
t.localPosition = td.Position;
1662+
else
1663+
t.localPosition = Vector3.MoveTowards(t.localPosition, posGoal, rate * delta * multiplier);
1664+
}
16591665

1660-
float multiplier = 1f;
1661-
int queueCount = _goalDataQueue.Count;
1662-
//Increase move rate slightly if over queue count.
1663-
if (queueCount > _interpolation + 1)
1664-
multiplier += 0.05f;
1666+
//Rotation.
1667+
if (_synchronizeRotation)
1668+
{
1669+
rate = rd.Rotation;
1670+
// ReSharper disable once CompareOfFloatsByEqualityOperator
1671+
if (rate == -1f)
1672+
t.localRotation = td.Rotation;
1673+
else
1674+
t.localRotation = Quaternion.RotateTowards(t.localRotation, td.Rotation, rate * delta);
1675+
}
16651676

1666-
//Rate to update. Changes per property.
1667-
float rate;
1668-
Transform t = _cachedTransform;
1677+
//Scale.
1678+
if (_synchronizeScale)
1679+
{
1680+
rate = rd.Scale;
1681+
// ReSharper disable once CompareOfFloatsByEqualityOperator
1682+
if (rate == -1f)
1683+
t.localScale = td.Scale;
1684+
else
1685+
t.localScale = Vector3.MoveTowards(t.localScale, td.Scale, rate * delta);
1686+
}
16691687

1670-
//Snap any bits of the transform that should be.
1671-
SnapProperties(td);
1688+
float timeRemaining = rd.TimeRemaining - delta * multiplier;
1689+
if (timeRemaining < -delta)
1690+
timeRemaining = -delta;
1691+
rd.TimeRemaining = timeRemaining;
16721692

1673-
//Position.
1674-
if (_synchronizePosition)
1675-
{
1676-
rate = rd.Position;
1677-
Vector3 posGoal = td.ExtrapolationState == TransformData.ExtrapolateState.Active && !_lastReceiveReliable ? td.ExtrapolatedPosition : td.Position;
1678-
// ReSharper disable once CompareOfFloatsByEqualityOperator
1679-
if (rate == -1f)
1680-
t.localPosition = td.Position;
1681-
else
1682-
t.localPosition = Vector3.MoveTowards(t.localPosition, posGoal, rate * delta * multiplier);
1693+
if (rd.TimeRemaining <= 0f)
1694+
{
1695+
float leftOver = Mathf.Abs(rd.TimeRemaining);
1696+
//If more in buffer then run next buffer.
1697+
if (queueCount > 0)
1698+
{
1699+
SetCurrentGoalData(_goalDataQueue.Dequeue());
1700+
if (leftOver > 0f)
1701+
MoveToTarget(leftOver);
1702+
}
1703+
//No more in buffer, see if can extrapolate.
1704+
else
1705+
{
1706+
/* If everything matches up then end queue.
1707+
* Otherwise let it play out until stuff
1708+
* aligns. Generally the time remaining is enough
1709+
* but every once in awhile something goes funky
1710+
* and it's thrown off. */
1711+
if (!HasChanged(td))
1712+
_currentGoalData = null;
1713+
OnInterpolationComplete?.Invoke();
1714+
}
1715+
}
16831716
}
1717+
}
16841718

1685-
//Rotation.
1686-
if (_synchronizeRotation)
1719+
/// <summary>
1720+
/// True if settings are configured to smooth with the current network state.
1721+
/// </summary>
1722+
/// <returns></returns>
1723+
public bool DoSettingsAllowSmoothing()
1724+
{
1725+
//If client auth and the owner don't move towards target.
1726+
if (_clientAuthoritative)
16871727
{
1688-
rate = rd.Rotation;
1689-
// ReSharper disable once CompareOfFloatsByEqualityOperator
1690-
if (rate == -1f)
1691-
t.localRotation = td.Rotation;
1692-
else
1693-
t.localRotation = Quaternion.RotateTowards(t.localRotation, td.Rotation, rate * delta);
1728+
if (IsOwner || TakenOwnership)
1729+
return false;
16941730
}
1695-
1696-
//Scale.
1697-
if (_synchronizeScale)
1731+
else
16981732
{
1699-
rate = rd.Scale;
1700-
// ReSharper disable once CompareOfFloatsByEqualityOperator
1701-
if (rate == -1f)
1702-
t.localScale = td.Scale;
1703-
else
1704-
t.localScale = Vector3.MoveTowards(t.localScale, td.Scale, rate * delta);
1733+
//If not client authoritative, is owner, and don't sync to owner.
1734+
if (IsOwner && !_sendToOwner)
1735+
return false;
17051736
}
17061737

1707-
float timeRemaining = rd.TimeRemaining - delta * multiplier;
1708-
if (timeRemaining < -delta)
1709-
timeRemaining = -delta;
1710-
rd.TimeRemaining = timeRemaining;
1738+
//True if not client controlled.
1739+
bool controlledByClient = _clientAuthoritative && Owner.IsActive;
1740+
//If not controlled by client and is server then no reason to move.
1741+
if (!controlledByClient && IsServerInitialized)
1742+
return false;
17111743

1712-
if (rd.TimeRemaining <= 0f)
1713-
{
1714-
float leftOver = Mathf.Abs(rd.TimeRemaining);
1715-
//If more in buffer then run next buffer.
1716-
if (queueCount > 0)
1717-
{
1718-
SetCurrentGoalData(_goalDataQueue.Dequeue());
1719-
if (leftOver > 0f)
1720-
MoveToTarget(leftOver);
1721-
}
1722-
//No more in buffer, see if can extrapolate.
1723-
else
1724-
{
1725-
/* If everything matches up then end queue.
1726-
* Otherwise let it play out until stuff
1727-
* aligns. Generally the time remaining is enough
1728-
* but every once in awhile something goes funky
1729-
* and it's thrown off. */
1730-
if (!HasChanged(td))
1731-
_currentGoalData = null;
1732-
OnInterpolationComplete?.Invoke();
1733-
}
1734-
}
1735-
}
1744+
return true;
17361745
}
17371746

17381747
/// <summary>
@@ -1978,11 +1987,11 @@ private ChangedDelta GetChanged(Vector3 lastPosition, Quaternion lastRotation, V
19781987

19791988
if (changed != ChangedDelta.Unset && ParentBehaviour != null)
19801989
changed |= ChangedDelta.Nested;
1981-
1990+
19821991
//If added scale or childed then also add extended.
19831992
if (startChanged != changed)
19841993
changed |= ChangedDelta.Extended;
1985-
1994+
19861995
return changed;
19871996
}
19881997
#endregion

Assets/FishNet/Runtime/Generated/Component/TickSmoothing/Editor/NetworkTickSmootherEditor.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ public class NetworkTickSmootherEditor : Editor
1010
{
1111
private SerializedProperty _initializationSettings;
1212
private SerializedProperty _controllerMovementSettings;
13+
private SerializedProperty _favorPredictionNetworkTransform;
1314
private SerializedProperty _spectatorMovementSettings;
1415
private bool _showControllerSmoothingSettings;
1516
private bool _showSpectatorSmoothingSettings;
1617

1718
protected virtual void OnEnable()
1819
{
1920
_initializationSettings = serializedObject.FindProperty(nameof(_initializationSettings));
21+
_favorPredictionNetworkTransform = serializedObject.FindProperty(nameof(_favorPredictionNetworkTransform));
2022
_controllerMovementSettings = serializedObject.FindProperty(nameof(_controllerMovementSettings));
2123
_spectatorMovementSettings = serializedObject.FindProperty(nameof(_spectatorMovementSettings));
2224
}
@@ -29,17 +31,19 @@ public override void OnInspectorGUI()
2931
EditorGUILayout.ObjectField("Script:", MonoScript.FromMonoBehaviour((NetworkTickSmoother)target), typeof(NetworkTickSmoother), false);
3032
GUI.enabled = true;
3133

32-
// EditorGUILayout.LabelField("Initialization Settings", EditorStyles.boldLabel);
34+
EditorGUILayout.PropertyField(_favorPredictionNetworkTransform);
3335

3436
EditorGUILayout.PropertyField(_initializationSettings);
3537

36-
_showControllerSmoothingSettings = EditorGUILayout.Foldout(_showControllerSmoothingSettings, new GUIContent("Controller Smoothing", "Smoothing applied when object controller. This would be the owner, or if there is no owner and are also server."));
38+
_showControllerSmoothingSettings = EditorGUILayout.Foldout(_showControllerSmoothingSettings, new GUIContent("Controller", "Smoothing applied when object controller. This would be the owner, or if there is no owner and are also server."));
3739
if (_showControllerSmoothingSettings)
3840
EditorGUILayout.PropertyField(_controllerMovementSettings);
3941

4042
_showSpectatorSmoothingSettings = EditorGUILayout.Foldout(_showSpectatorSmoothingSettings, new GUIContent("Spectator Smoothing", "Smoothing applied when object not the owner. This is when server and there is an owner, or when client and not the owner."));
4143
if (_showSpectatorSmoothingSettings)
44+
{
4245
EditorGUILayout.PropertyField(_spectatorMovementSettings);
46+
}
4347

4448

4549
// EditorGUI.indentLevel--;

Assets/FishNet/Runtime/Generated/Component/TickSmoothing/InitializationSettings.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,31 @@ public struct InitializationSettings
4545
/// </summary>
4646
[System.NonSerialized]
4747
internal TimeManager InitializingTimeManager;
48+
/// <summary>
49+
/// True to disable smoothing when the NetworkObject enables prediction, specifies a NetworkTransform to use, and that NetworkTransform is currently smoothing.
50+
/// </summary>
51+
[System.NonSerialized]
52+
internal bool FavorPredictionNetworkTransform;
4853

49-
public void SetNetworkedRuntimeValues(NetworkBehaviour initializingNetworkBehaviour, Transform graphicalTransform)
54+
public void SetNetworkedRuntimeValues(NetworkBehaviour initializingNetworkBehaviour, Transform graphicalTransform, bool favorPredictionNetworkTransform)
5055
{
5156
InitializingNetworkBehaviour = initializingNetworkBehaviour;
52-
GraphicalTransform = graphicalTransform;
5357
InitializingTimeManager = initializingNetworkBehaviour.TimeManager;
58+
GraphicalTransform = graphicalTransform;
59+
60+
FavorPredictionNetworkTransform = favorPredictionNetworkTransform;
5461
}
5562

5663
/// <summary>
5764
/// Sets values used at runtime. NetworkBehaviour is nullified when calling this method.
5865
/// </summary>
5966
public void SetOfflineRuntimeValues(TimeManager timeManager, Transform graphicalTransform)
6067
{
61-
InitializingNetworkBehaviour = null;
6268
GraphicalTransform = graphicalTransform;
6369
InitializingTimeManager = timeManager;
70+
71+
InitializingNetworkBehaviour = null;
72+
FavorPredictionNetworkTransform = false;
6473
}
6574
}
6675
}

0 commit comments

Comments
 (0)