Skip to content

Commit bab3abc

Browse files
update
Some adjustments to handle coming to a stop and to no longer clamp the timespan between state updates for LerpExtrapolateBlend and SmoothDampening. Adding fixed delta to server time (if it is of any value then multiple fixed updates have run within a single frame). Updated XML API documentation (again).
1 parent 049b1c3 commit bab3abc

File tree

2 files changed

+254
-115
lines changed

2 files changed

+254
-115
lines changed

com.unity.netcode.gameobjects/Runtime/Components/Interpolator/BufferedLinearInterpolator.cs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,17 @@ private void TryConsumeFromBuffer(double renderTime, double minDeltaTime, double
312312
var currentTargetTimeReached = false;
313313
var dequeuedCount = 0;
314314

315+
// In the event there is nothing left in the queue (i.e. motion/change stopped), we still need to determine if the target has been reached.
316+
if (!noStateSet && m_BufferQueue.Count == 0)
317+
{
318+
if (!InterpolateState.TargetReached)
319+
{
320+
InterpolateState.TargetReached = IsAproximately(InterpolateState.CurrentValue, InterpolateState.Target.Value.Item);
321+
}
322+
return;
323+
}
324+
325+
// Continue to process any remaining state updates in the queue (if any)
315326
while (m_BufferQueue.TryPeek(out BufferedItem potentialItem))
316327
{
317328
// If we are still on the same buffered item (FIFO Queue), then exit early as there is nothing
@@ -325,7 +336,7 @@ private void TryConsumeFromBuffer(double renderTime, double minDeltaTime, double
325336
{
326337
potentialItemNeedsProcessing = (potentialItem.TimeSent <= renderTime) && potentialItem.TimeSent >= InterpolateState.Target.Value.TimeSent;
327338
currentTargetTimeReached = InterpolateState.TargetTimeAproximatelyReached(potentialItemNeedsProcessing ? 1.0f : 0.85f) || InterpolateState.TargetReached;
328-
if (!potentialItemNeedsProcessing && !InterpolateState.TargetReached)
339+
if (!InterpolateState.TargetReached)
329340
{
330341
InterpolateState.TargetReached = IsAproximately(InterpolateState.CurrentValue, InterpolateState.Target.Value.Item);
331342
}
@@ -366,14 +377,19 @@ private void TryConsumeFromBuffer(double renderTime, double minDeltaTime, double
366377
if (isPredictedLerp)
367378
{
368379
InterpolateState.Phase1Value = InterpolateState.PreviousValue;
369-
InterpolateState.Phase2Value = Interpolate(InterpolateState.PredictValue, target.Item, InterpolateState.AverageDeltaTime);
380+
InterpolateState.Phase2Value = Interpolate(InterpolateState.PreviousValue, target.Item, InterpolateState.AverageDeltaTime);
381+
}
382+
else
383+
{
384+
InterpolateState.PredictValue = InterpolateState.PreviousValue;
385+
InterpolateState.PreviousValue = InterpolateState.CurrentValue;
370386
}
371387
InterpolateState.MaxDeltaTime = maxDeltaTime;
372388
InterpolateState.PredictingNext = m_BufferQueue.Count > 0;
373389
}
374-
// TODO: We might consider creating yet another queue to add these items to and assure that the time is accelerated
375-
// for each item as opposed to losing the resolution of the values.
376-
InterpolateState.SetTimeToTarget(Math.Clamp((float)(target.TimeSent - startTime), minDeltaTime, maxDeltaTime * dequeuedCount));
390+
// We continue to stretch the time out if we are far behind in processing the buffer.
391+
// TODO: We need to compress time when there is a large amount of items to be processed.
392+
InterpolateState.SetTimeToTarget(Math.Max((float)(target.TimeSent - startTime), minDeltaTime));
377393
InterpolateState.Target = target;
378394
}
379395
}
@@ -446,17 +462,29 @@ internal T Update(float deltaTime, double tickLatencyAsTime, double minDeltaTime
446462
// If lerp smoothing is enabled, then smooth current value towards the target value
447463
if (LerpSmoothEnabled)
448464
{
449-
// Progress by 1/3rd of the way towards the target in order to assure the target is reached sooner
450-
var oneThirdPoint = Interpolate(InterpolateState.CurrentValue, targetValue, 0.3333f);
451465
// Apply the smooth lerp from the oneThirpoint to the target to help smooth the final value
452-
InterpolateState.CurrentValue = Interpolate(oneThirdPoint, targetValue, deltaTime / MaximumInterpolationTime);
466+
InterpolateState.CurrentValue = Interpolate(InterpolateState.CurrentValue, targetValue, deltaTime / MaximumInterpolationTime);
453467
}
454468
else
455469
{
456470
// Otherwise, just assign the target value.
457471
InterpolateState.CurrentValue = targetValue;
458472
}
459473
}
474+
else // If the target is reached and we have no more state updates, we want to check to see if we need to reset.
475+
if (m_BufferQueue.Count == 0)
476+
{
477+
// When the delta between the time sent and the current tick latency time-window is greater than the max delta time
478+
// plus the minimum delta time (a rough estimate of time to wait before we consider rate of change equal to zero),
479+
// we will want to reset the interpolator with the current known value. This prevents the next received state update's
480+
// time to be calculated against the last calculated time which if there is an extended period of time between the two
481+
// it would cause a large delta time period between the two states (i.e. it stops moving for a second or two and then
482+
// starts moving again).
483+
if ((tickLatencyAsTime - InterpolateState.Target.Value.TimeSent) > InterpolateState.MaxDeltaTime + minDeltaTime)
484+
{
485+
InterpolateState.Reset(InterpolateState.CurrentValue);
486+
}
487+
}
460488
}
461489
m_NbItemsReceivedThisFrame = 0;
462490
return InterpolateState.CurrentValue;
@@ -567,8 +595,7 @@ public T Update(float deltaTime, double renderTime, double serverTime)
567595
if (LerpSmoothEnabled)
568596
{
569597
// Assure our MaximumInterpolationTime is valid and that the second lerp time ranges between deltaTime and 1.0f.
570-
var secondLerpTime = Mathf.Clamp(deltaTime / MaximumInterpolationTime, deltaTime, 1.0f);
571-
InterpolateState.CurrentValue = Interpolate(InterpolateState.CurrentValue, target, secondLerpTime);
598+
InterpolateState.CurrentValue = Interpolate(InterpolateState.CurrentValue, target, deltaTime / MaximumInterpolationTime);
572599
}
573600
else
574601
{

0 commit comments

Comments
 (0)