@@ -87,8 +87,10 @@ private float GetPrecision()
8787 /// </summary>
8888 protected internal struct BufferedItem
8989 {
90+ public Transform Parent ;
91+
9092 /// <summary>
91- /// THe item identifier
93+ /// The item identifier
9294 /// </summary>
9395 public int ItemId ;
9496 /// <summary>
@@ -111,6 +113,7 @@ public BufferedItem(T item, double timeSent, int itemId)
111113 Item = item ;
112114 TimeSent = timeSent ;
113115 ItemId = itemId ;
116+ Parent = null ;
114117 }
115118
116119 /// <summary>
@@ -124,6 +127,7 @@ public BufferedItem(T item, double timeSent)
124127 TimeSent = timeSent ;
125128 // Generate a unique item id based on the time to the 2nd decimal place
126129 ItemId = ( int ) ( timeSent * 100 ) ;
130+ Parent = null ;
127131 }
128132 }
129133
@@ -225,7 +229,9 @@ public void Reset(T currentValue)
225229 /// </summary>
226230 internal float MaxInterpolationBound = 3.0f ;
227231 internal bool EndOfBuffer => m_BufferQueue . Count == 0 ;
232+ internal bool StoreAsWorldSpace ;
228233 internal bool InLocalSpace ;
234+ internal Transform Parent ;
229235
230236 private double m_LastMeasurementAddedTime = 0.0f ;
231237 private int m_BufferCount ;
@@ -257,23 +263,42 @@ public void Clear()
257263 /// <param name="targetValue">The target value to reset the interpolator to</param>
258264 /// <param name="serverTime">The current server time</param>
259265 public void ResetTo ( T targetValue , double serverTime )
266+ {
267+ ResetTo ( null , targetValue , serverTime ) ;
268+ }
269+
270+ internal void ResetTo ( Transform parent , T targetValue , double serverTime )
260271 {
261272 // Clear the interpolator
262273 Clear ( ) ;
263- InternalReset ( targetValue , serverTime ) ;
274+ InternalReset ( parent , targetValue , serverTime ) ;
264275 }
265276
266277 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
267- private void InternalReset ( T targetValue , double serverTime , bool addMeasurement = true )
278+ private bool ConvertTransformSpace ( Transform parent )
279+ {
280+ return StoreAsWorldSpace && parent != null && InLocalSpace ;
281+ }
282+
283+
284+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
285+ private void InternalReset ( Transform parent , T targetValue , double serverTime , bool addMeasurement = true )
268286 {
269287 m_RateOfChange = default ;
270- // Set our initial value
271- InterpolateState . Reset ( targetValue ) ;
288+ var currentValue = targetValue ;
289+ if ( ConvertTransformSpace ( parent ) )
290+ {
291+ // Keep everything in world space
292+ currentValue = OnConvertTransformSpace ( parent , targetValue , false ) ;
293+ }
294+
295+ // Set our initial value (what we will interpolate from relative to the next state update received)
296+ InterpolateState . Reset ( currentValue ) ;
272297
273298 if ( addMeasurement )
274299 {
275300 // Add the first measurement for our baseline
276- AddMeasurement ( targetValue , serverTime ) ;
301+ AddMeasurement ( parent , targetValue , serverTime ) ;
277302 }
278303 }
279304
@@ -586,8 +611,20 @@ internal T UpdateInternal(float deltaTime, NetworkTime serverTime, int ticksAgo
586611 /// <param name="newMeasurement">The new measurement value to use</param>
587612 /// <param name="sentTime">The time to record for measurement</param>
588613 public void AddMeasurement ( T newMeasurement , double sentTime )
614+ {
615+ AddMeasurement ( null , newMeasurement , sentTime ) ;
616+ }
617+
618+ internal void AddMeasurement ( Transform parent , T newMeasurement , double sentTime )
589619 {
590620 m_NbItemsReceivedThisFrame ++ ;
621+ var previousMeasurement = newMeasurement ;
622+ // If enabled, convert everything to world space if in local space.
623+ if ( ConvertTransformSpace ( parent ) )
624+ {
625+ // Keep everything in world space
626+ newMeasurement = OnConvertTransformSpace ( parent , newMeasurement , false ) ;
627+ }
591628
592629 // This situation can happen after a game is paused. When starting to receive again, the server will have sent a bunch of messages in the meantime
593630 // instead of going through thousands of value updates just to get a big teleport, we're giving up on interpolation and teleporting to the latest value
@@ -598,9 +635,12 @@ public void AddMeasurement(T newMeasurement, double sentTime)
598635 // Clear the interpolator
599636 Clear ( ) ;
600637 // Reset to the new value but don't automatically add the measurement (prevents recursion)
601- InternalReset ( newMeasurement , sentTime , false ) ;
638+ InternalReset ( parent , newMeasurement , sentTime , false ) ;
602639 m_LastMeasurementAddedTime = sentTime ;
603- m_LastBufferedItemReceived = new BufferedItem ( newMeasurement , sentTime , m_BufferCount ) ;
640+ m_LastBufferedItemReceived = new BufferedItem ( newMeasurement , sentTime , m_BufferCount )
641+ {
642+ Parent = parent ,
643+ } ;
604644 // Next line keeps renderTime above m_StartTimeConsumed. Fixes pause/unpause issues
605645 m_BufferQueue . Enqueue ( m_LastBufferedItemReceived ) ;
606646 }
@@ -611,7 +651,10 @@ public void AddMeasurement(T newMeasurement, double sentTime)
611651 if ( sentTime > m_LastMeasurementAddedTime || m_BufferCount == 0 )
612652 {
613653 m_BufferCount ++ ;
614- m_LastBufferedItemReceived = new BufferedItem ( newMeasurement , sentTime , m_BufferCount ) ;
654+ m_LastBufferedItemReceived = new BufferedItem ( newMeasurement , sentTime , m_BufferCount )
655+ {
656+ Parent = parent ,
657+ } ;
615658 m_BufferQueue . Enqueue ( m_LastBufferedItemReceived ) ;
616659 m_LastMeasurementAddedTime = sentTime ;
617660 }
@@ -624,7 +667,14 @@ public void AddMeasurement(T newMeasurement, double sentTime)
624667 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
625668 public T GetInterpolatedValue ( )
626669 {
627- return InterpolateState . CurrentValue ;
670+ var currentValue = InterpolateState . CurrentValue ;
671+ // If we are auto adjusting the value from world to local
672+ if ( ConvertTransformSpace ( Parent ) )
673+ {
674+ // Convert to local space
675+ currentValue = OnConvertTransformSpace ( Parent , currentValue , true ) ;
676+ }
677+ return currentValue ;
628678 }
629679
630680 /// <summary>
0 commit comments