Skip to content

Commit 45ed0e1

Browse files
update
Still work in progress. Needs some clean up, but it is looking promising.
1 parent d5dfc63 commit 45ed0e1

3 files changed

Lines changed: 252 additions & 54 deletions

File tree

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

Lines changed: 198 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ public abstract class BufferedLinearInterpolator<T> where T : struct
1515
internal float MaxInterpolationBound = 1.0f;
1616
protected internal struct BufferedItem
1717
{
18+
public int ItemId;
1819
public T Item;
1920
public double TimeSent;
2021

21-
public BufferedItem(T item, double timeSent)
22+
public BufferedItem(T item, double timeSent,int itemId)
2223
{
2324
Item = item;
2425
TimeSent = timeSent;
26+
ItemId = itemId;
2527
}
2628
}
2729

@@ -34,7 +36,7 @@ public BufferedItem(T item, double timeSent)
3436

3537
protected internal readonly Queue<BufferedItem> m_Buffer = new Queue<BufferedItem>(k_BufferCountLimit);
3638

37-
39+
private int m_BufferCount;
3840

3941
// Buffer consumption scenarios
4042
// Perfect case consumption
@@ -88,6 +90,7 @@ internal void ConvertTransformSpace(Transform transform, bool inLocalSpace)
8890
public void Clear()
8991
{
9092
m_Buffer.Clear();
93+
m_BufferCount = 0;
9194
m_CurrentInterpValue = default;
9295
m_LastMeasurementAddedTime = 0.0;
9396
InterpolateState.Reset(default);
@@ -176,18 +179,26 @@ internal struct CurrentState
176179
{
177180
public BufferedItem? Target;
178181

182+
public double ServerTime;
179183
public double RelativeTime;
184+
public double DeltaTime;
180185

181186
public T CurrentValue;
187+
public T PreviousValue;
182188

183189
public float LerpT;
184190

191+
public float LerpV;
192+
185193
public void Reset(T currentValue)
186194
{
187195
CurrentValue = currentValue;
196+
PreviousValue = currentValue;
188197
// When reset, we consider ourselves to have already arrived at the target (even if no target is set)
189198
LerpT = 1.0f;
199+
LerpV = 1.0f;
190200
RelativeTime = 0.0;
201+
DeltaTime = 0.0;
191202
}
192203
}
193204

@@ -235,15 +246,192 @@ private void TryConsumeFromBuffer(double renderTime, double serverTime)
235246
}
236247
}
237248

249+
250+
#if UNITY_EDITOR
251+
internal bool EnableLogging = false;
252+
internal ulong NetworkObjectId;
253+
internal ushort NetworkBehaviourId;
254+
255+
private double m_LastDebugUpdate = 0.0;
256+
257+
private double m_AvgTimeDelta = 0.0;
258+
259+
private float m_LowestLerpT = float.MaxValue;
260+
private float m_LerpTAverage = 0.0f;
261+
private int m_MaxBufferedItems = 0;
262+
private float m_AverageBufferCount = 0.0f;
263+
264+
private void LogInfo(double serverTime)
265+
{
266+
if (!EnableLogging)
267+
{
268+
return;
269+
}
270+
if (m_LowestLerpT > InterpolateState.LerpT)
271+
{
272+
m_LowestLerpT = InterpolateState.LerpT;
273+
}
274+
275+
if (m_LerpTAverage == 0.0f)
276+
{
277+
m_LerpTAverage = InterpolateState.LerpT;
278+
}
279+
else
280+
{
281+
m_LerpTAverage = (m_LerpTAverage + InterpolateState.LerpT) * 0.5f;
282+
}
283+
284+
if (m_MaxBufferedItems < m_Buffer.Count)
285+
{
286+
m_MaxBufferedItems = m_Buffer.Count;
287+
}
288+
289+
if (m_AverageBufferCount == 0.0f)
290+
{
291+
m_AverageBufferCount = (m_AverageBufferCount + m_Buffer.Count) * 0.5f;
292+
}
293+
294+
if (m_AvgTimeDelta == 0.0)
295+
{
296+
m_AvgTimeDelta = InterpolateState.DeltaTime;
297+
}
298+
else
299+
{
300+
m_AvgTimeDelta += InterpolateState.DeltaTime;
301+
m_AvgTimeDelta *= 0.5;
302+
}
303+
304+
if (m_LastDebugUpdate < serverTime)
305+
{
306+
Debug.Log($"[{m_Name}][{NetworkObjectId}-{NetworkBehaviourId}][{InterpolateState.Target.Value.ItemId}] Min LerpT: {m_LowestLerpT} | Avg LerpT: {m_LerpTAverage} | Max Count: {m_MaxBufferedItems} | Avg Count: {m_AverageBufferCount} | Avg TD: {m_AvgTimeDelta}");
307+
m_LastDebugUpdate = serverTime + 1.0;
308+
m_AverageBufferCount = 0.0f;
309+
m_MaxBufferedItems = 0;
310+
m_LerpTAverage = 0.0f;
311+
m_LowestLerpT = float.MaxValue;
312+
}
313+
}
314+
#endif
315+
316+
private void TryConsumeFromBuffer(NetworkTime networkTime, NetworkTimeSystem networkTimeSystem)
317+
{
318+
// If we don't have our initial buffered item/starting point or our end point or the end point's time sent is less than the
319+
// render time
320+
var renderTime = networkTime.TimeTicksAgo(2).Time;
321+
if (!InterpolateState.Target.HasValue || (InterpolateState.Target.Value.TimeSent <= renderTime && InterpolateState.LerpT >= 1.0f))
322+
{
323+
BufferedItem? previousItem = null;
324+
while (m_Buffer.TryPeek(out BufferedItem potentialItem))
325+
{
326+
// If we are still on the same buffered item (FIFO Queue), then exit early as there is nothing
327+
// to consume.
328+
if (previousItem.HasValue && previousItem.Value.TimeSent == potentialItem.TimeSent)
329+
{
330+
break;
331+
}
332+
333+
// At a minimum, the next item should be equal to or less than the server time
334+
if (potentialItem.TimeSent <= networkTimeSystem.ServerTime)
335+
{
336+
if (!InterpolateState.Target.HasValue || InterpolateState.Target.Value.TimeSent < potentialItem.TimeSent)
337+
{
338+
if (m_Buffer.TryDequeue(out BufferedItem target))
339+
{
340+
if (!InterpolateState.Target.HasValue)
341+
{
342+
InterpolateState.Target = target;
343+
InterpolateState.DeltaTime = networkTime.FixedDeltaTime;
344+
}
345+
else
346+
{
347+
#if UNITY_EDITOR
348+
LogInfo(networkTimeSystem.ServerTime);
349+
#endif
350+
InterpolateState.DeltaTime = networkTime.FixedDeltaTime;
351+
InterpolateState.Target = target;
352+
}
353+
//InterpolateState.RelativeTime = networkTime.FixedDeltaTime/2.75f;
354+
//InterpolateState.RelativeTime = networkTime.FixedDeltaTime / 3f;
355+
InterpolateState.RelativeTime = 0.0;
356+
InterpolateState.PreviousValue = InterpolateState.CurrentValue;
357+
InterpolateState.LerpT = 0.0f;
358+
InterpolateState.LerpV = 0.0f;
359+
InterpolateState.ServerTime = networkTimeSystem.ServerTime;
360+
break;
361+
}
362+
}
363+
else
364+
{
365+
break;
366+
}
367+
}
368+
if (!InterpolateState.Target.HasValue)
369+
{
370+
break;
371+
}
372+
previousItem = potentialItem;
373+
}
374+
}
375+
}
376+
377+
238378
/// <summary>
239-
/// Convenience version of 'Update' mainly for testing
240-
/// the reason we don't want to always call this version is so that on the calling side we can compute
241-
/// the renderTime once for the many things being interpolated (and the many interpolators per object)
379+
/// ** Recommended Usage **
380+
/// A more precise update for the buffered linear interpolator.
242381
/// </summary>
243382
/// <param name="deltaTime">time since call</param>
244383
/// <param name="serverTime">current server time</param>
245384
/// <returns>The newly interpolated value of type 'T'</returns>
246-
public T Update(float deltaTime, NetworkTime serverTime)
385+
public T Update(float deltaTime, NetworkTime serverTime, NetworkTimeSystem networkTimeSystem)
386+
{
387+
TryConsumeFromBuffer(serverTime, networkTimeSystem);
388+
389+
390+
// Only interpolate when there is a start and end point and we have not already reached the end value
391+
if (InterpolateState.Target.HasValue)
392+
{
393+
if (InterpolateState.LerpT < 1.0f)
394+
{
395+
var serverTimeDelta = Math.Max(0.000000000001, (networkTimeSystem.ServerTime - InterpolateState.ServerTime) + deltaTime);
396+
397+
InterpolateState.RelativeTime = Math.Min(InterpolateState.RelativeTime + serverTimeDelta, InterpolateState.DeltaTime);
398+
399+
#if UNITY_EDITOR
400+
//if (EnableLogging)
401+
//{
402+
// Debug.Log($"[{m_Name}][{NetworkObjectId}-{NetworkBehaviourId}][{InterpolateState.Target.Value.ItemId}] Server Time: {networkTimeSystem.ServerTime} | Time RDelta: {InterpolateState.RelativeTime} | Delta: {InterpolateState.DeltaTime}");
403+
//}
404+
#endif
405+
//var t = 1.0f - Mathf.Clamp((float)((m_EndTimeConsumed - renderTime) * rangeFactor), 0.0f, 1.0f);
406+
//var alt_t = 1.0f - Mathf.Clamp((float)((renderTime - m_StartTimeConsumed) * rangeFactor), 0.0f, 1.0f);
407+
InterpolateState.LerpT = (float)(InterpolateState.RelativeTime / InterpolateState.DeltaTime);
408+
InterpolateState.CurrentValue = Interpolate(InterpolateState.PreviousValue, InterpolateState.Target.Value.Item, InterpolateState.LerpT);
409+
m_CurrentInterpValue = InterpolateState.CurrentValue;
410+
//m_CurrentInterpValue = Interpolate(InterpolateState.TargetStartValue, InterpolateState.TargetEndValue, (deltaTime / MaximumInterpolationTime));
411+
//if (InterpolateState.LerpT < 1.0f)
412+
//{
413+
// m_CurrentInterpValue = Interpolate(m_CurrentInterpValue, InterpolateState.CurrentValue, 0.5f);
414+
//}
415+
//else
416+
//{
417+
// m_CurrentInterpValue = InterpolateState.CurrentValue;
418+
//}
419+
//if (InterpolateState.LerpT >= 1.0f)
420+
//{
421+
// InterpolateState.TargetValue = InterpolateState.CurrentValue;
422+
//}
423+
//InterpolateState.LerpV = Math.Min(InterpolateState.LerpV + (deltaTime / MaximumInterpolationTime), 1.0f);
424+
}
425+
}
426+
427+
m_NbItemsReceivedThisFrame = 0;
428+
return m_CurrentInterpValue;
429+
}
430+
431+
/// <summary>
432+
/// Used for internal testing
433+
/// </summary>
434+
internal T UpdateInternal(float deltaTime, NetworkTime serverTime)
247435
{
248436
return Update(deltaTime, serverTime.TimeTicksAgo(1).Time, serverTime.Time);
249437
}
@@ -299,7 +487,8 @@ public void AddMeasurement(T newMeasurement, double sentTime)
299487
{
300488
if (m_LastBufferedItemReceived.TimeSent < sentTime)
301489
{
302-
m_LastBufferedItemReceived = new BufferedItem(newMeasurement, sentTime);
490+
m_BufferCount++;
491+
m_LastBufferedItemReceived = new BufferedItem(newMeasurement, sentTime, m_BufferCount);
303492
ResetTo(newMeasurement, sentTime);
304493
// Next line keeps renderTime above m_StartTimeConsumed. Fixes pause/unpause issues
305494
m_Buffer.Enqueue(m_LastBufferedItemReceived);
@@ -310,7 +499,8 @@ public void AddMeasurement(T newMeasurement, double sentTime)
310499

311500
if (sentTime > m_LastMeasurementAddedTime)
312501
{
313-
m_LastBufferedItemReceived = new BufferedItem(newMeasurement, sentTime);
502+
m_BufferCount++;
503+
m_LastBufferedItemReceived = new BufferedItem(newMeasurement, sentTime, m_BufferCount);
314504
m_Buffer.Enqueue(m_LastBufferedItemReceived);
315505
m_LastMeasurementAddedTime = sentTime;
316506
}

com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3717,7 +3717,13 @@ private void UpdateInterpolation()
37173717
// Now only update the interpolators for the portions of the transform being synchronized
37183718
if (SynchronizePosition)
37193719
{
3720-
m_PositionInterpolator.Update(cachedDeltaTime, cachedRenderTime, cachedServerTime);
3720+
//m_PositionInterpolator.Update(cachedDeltaTime, cachedRenderTime, cachedServerTime);
3721+
#if UNITY_EDITOR
3722+
m_PositionInterpolator.NetworkObjectId = NetworkObjectId;
3723+
m_PositionInterpolator.NetworkBehaviourId = NetworkBehaviourId;
3724+
m_PositionInterpolator.EnableLogging = true;
3725+
#endif
3726+
m_PositionInterpolator.Update(cachedDeltaTime, m_CachedNetworkManager.ServerTime, m_CachedNetworkManager.NetworkTimeSystem);
37213727
}
37223728

37233729
if (SynchronizeRotation)
@@ -3726,12 +3732,14 @@ private void UpdateInterpolation()
37263732
// When using full precision Slerp towards the target rotation.
37273733
/// <see cref="BufferedLinearInterpolatorQuaternion.IsSlerp"/>
37283734
m_RotationInterpolator.IsSlerp = !UseHalfFloatPrecision;
3729-
m_RotationInterpolator.Update(cachedDeltaTime, cachedRenderTime, cachedServerTime);
3735+
//m_RotationInterpolator.Update(cachedDeltaTime, cachedRenderTime, cachedServerTime);
3736+
m_RotationInterpolator.Update(cachedDeltaTime, m_CachedNetworkManager.ServerTime, m_CachedNetworkManager.NetworkTimeSystem);
37303737
}
37313738

37323739
if (SynchronizeScale)
37333740
{
3734-
m_ScaleInterpolator.Update(cachedDeltaTime, cachedRenderTime, cachedServerTime);
3741+
//m_ScaleInterpolator.Update(cachedDeltaTime, cachedRenderTime, cachedServerTime);
3742+
m_ScaleInterpolator.Update(cachedDeltaTime, m_CachedNetworkManager.ServerTime, m_CachedNetworkManager.NetworkTimeSystem);
37353743
}
37363744
}
37373745
}

0 commit comments

Comments
 (0)