@@ -27,6 +27,15 @@ public class IndividualPlayerPanelUpdater : MonoBehaviour
2727 public PanelElementDescriptor SilenceField ;
2828 public PanelElementDescriptor VisemeField ;
2929
30+ // Avatar data chain debug fields
31+ public PanelElementDescriptor AvatarReceiveField ;
32+ public PanelElementDescriptor AvatarStagingField ;
33+ public PanelElementDescriptor AvatarInterpField ;
34+ public PanelElementDescriptor AvatarMetaField ;
35+
36+ private byte _lastHighestSequence ;
37+ private bool _lastHighestSeqValid ;
38+
3039 private float _updateTimer ;
3140 private const float UpdateInterval = 0.2f ;
3241
@@ -51,6 +60,10 @@ private void DisableRichTextOnce()
5160 EncodedBufferField ? . DisableRichText ( ) ;
5261 SilenceField ? . DisableRichText ( ) ;
5362 VisemeField ? . DisableRichText ( ) ;
63+ AvatarReceiveField ? . DisableRichText ( ) ;
64+ AvatarStagingField ? . DisableRichText ( ) ;
65+ AvatarInterpField ? . DisableRichText ( ) ;
66+ AvatarMetaField ? . DisableRichText ( ) ;
5467 }
5568
5669 private void FreezeLayoutOnce ( )
@@ -73,6 +86,10 @@ private void FreezeLayoutOnce()
7386 EncodedBufferField ? . FreezeLayoutSize ( 140f ) ;
7487 SilenceField ? . FreezeLayoutSize ( 90f ) ;
7588 VisemeField ? . FreezeLayoutSize ( 90f ) ;
89+ AvatarReceiveField ? . FreezeLayoutSize ( 120f ) ;
90+ AvatarStagingField ? . FreezeLayoutSize ( 140f ) ;
91+ AvatarInterpField ? . FreezeLayoutSize ( 140f ) ;
92+ AvatarMetaField ? . FreezeLayoutSize ( 170f ) ;
7693 }
7794
7895 private void Update ( )
@@ -127,6 +144,7 @@ private void Update()
127144 if ( RangesField != null ) RangesField . SetDescription ( "No data" ) ;
128145 UpdateBufferField ( ) ;
129146 UpdateAudioDebugFields ( ) ;
147+ UpdateAvatarDataDebugFields ( ) ;
130148 return ;
131149 }
132150
@@ -138,6 +156,7 @@ private void Update()
138156 if ( RangesField != null ) RangesField . SetDescription ( "Player not found" ) ;
139157 UpdateBufferField ( ) ;
140158 UpdateAudioDebugFields ( ) ;
159+ UpdateAvatarDataDebugFields ( ) ;
141160 return ;
142161 }
143162
@@ -162,6 +181,7 @@ private void Update()
162181 if ( RangesField != null ) RangesField . SetDescription ( "Not in snapshot" ) ;
163182 UpdateBufferField ( ) ;
164183 UpdateAudioDebugFields ( ) ;
184+ UpdateAvatarDataDebugFields ( ) ;
165185 return ;
166186 }
167187
@@ -219,6 +239,7 @@ private void Update()
219239
220240 UpdateBufferField ( ) ;
221241 UpdateAudioDebugFields ( ) ;
242+ UpdateAvatarDataDebugFields ( ) ;
222243
223244 // Only count ticks that reached the full-data path — early-returns
224245 // above set fields to "N/A"/"No data" which would lock at a too-small
@@ -404,6 +425,75 @@ private void SetAudioDebugAll(string message)
404425 if ( VisemeField != null ) VisemeField . SetDescription ( message ) ;
405426 }
406427
428+ private void UpdateAvatarDataDebugFields ( )
429+ {
430+ if ( RemotePlayer == null || RemotePlayer . NetworkReceiver == null )
431+ {
432+ SetAvatarDataDebugAll ( "No receiver" ) ;
433+ return ;
434+ }
435+
436+ var receiver = RemotePlayer . NetworkReceiver ;
437+
438+ if ( AvatarReceiveField != null && BasisSettingsDefaults . AvatarDataDebugShowReceive . RawValue )
439+ {
440+ byte highest = receiver . HighestSequence ;
441+ int seen = receiver . SeenPackets ;
442+ int queued = receiver . PayloadQueue . Count ;
443+ int newThisTick = _lastHighestSeqValid ? unchecked ( ( byte ) ( highest - _lastHighestSequence ) ) : 0 ;
444+ _lastHighestSequence = highest ;
445+ _lastHighestSeqValid = true ;
446+ string state = seen == 0 ? "None" : seen == 1 ? "Initial" : "Streaming" ;
447+
448+ AvatarReceiveField . SetDescription (
449+ $ "State: { state } | Queued: { queued } \n " +
450+ $ "Highest Seq: { highest } | New this tick: +{ newThisTick } ") ;
451+ }
452+
453+ if ( AvatarStagingField != null && BasisSettingsDefaults . AvatarDataDebugShowStaging . RawValue )
454+ {
455+ var cur = receiver . Current ;
456+ var nxt = receiver . Next ;
457+ bool hasCur = receiver . HasCurrentBuffer && cur != null ;
458+ bool hasNxt = receiver . HasNextBuffer && nxt != null ;
459+ double windowMs = ( hasCur && hasNxt ) ? ( nxt . ServerTimeSeconds - cur . ServerTimeSeconds ) * 1000.0 : 0.0 ;
460+
461+ AvatarStagingField . SetDescription (
462+ $ "Staged: { receiver . StagedCount } | Data Ready: { ( receiver . IsDataReady ? "Yes" : "No" ) } \n " +
463+ $ "Cur Seq: { ( hasCur ? cur . Sequence . ToString ( ) : "-" ) } | Next Seq: { ( hasNxt ? nxt . Sequence . ToString ( ) : "-" ) } \n " +
464+ $ "Window: { windowMs : F1} ms") ;
465+ }
466+
467+ if ( AvatarInterpField != null && BasisSettingsDefaults . AvatarDataDebugShowInterp . RawValue )
468+ {
469+ AvatarInterpField . SetDescription (
470+ $ "t: { receiver . InterpolationTimeDebug : F3} | Rate: { receiver . LastPlaybackRate : F3} x (0.85-1.35)\n " +
471+ $ "Jitter Depth: { receiver . DynamicJitterDepth : F2} (min { BasisNetworkReceiver . MinJitterDepth } / max { BasisNetworkReceiver . MaxJitterDepth } )\n " +
472+ $ "Buffer Holds: { ( receiver . HasBufferHolds ? "Yes" : "No" ) } ") ;
473+ }
474+
475+ if ( AvatarMetaField != null && BasisSettingsDefaults . AvatarDataDebugShowMeta . RawValue )
476+ {
477+ receiver . GetLatestNetworkPose ( out var pos , out _ , out var scale ) ;
478+ float [ ] eom = receiver . EyesAndMouth ;
479+ float mouth = eom != null && eom . Length > 4 ? eom [ 4 ] : 0f ;
480+
481+ AvatarMetaField . SetDescription (
482+ $ "Scale: { receiver . ApplyingScale . x : F2} | Human: { receiver . CachedHumanScaleDebug : F2} | Net: { scale . x : F2} \n " +
483+ $ "Hips: ({ pos . x : F1} , { pos . y : F1} , { pos . z : F1} )\n " +
484+ $ "LOD: { RemotePlayer . CurrentLodLevel } | PoseSkip: { RemotePlayer . PoseSkipCounter } \n " +
485+ $ "InAvatar: { ( RemotePlayer . InAvatarRange ? "Y" : "N" ) } | OutOfRange: { ( RemotePlayer . OutOfRangeFromLocal ? "Y" : "N" ) } | Mouth: { mouth : F2} ") ;
486+ }
487+ }
488+
489+ private void SetAvatarDataDebugAll ( string message )
490+ {
491+ if ( AvatarReceiveField != null ) AvatarReceiveField . SetDescription ( message ) ;
492+ if ( AvatarStagingField != null ) AvatarStagingField . SetDescription ( message ) ;
493+ if ( AvatarInterpField != null ) AvatarInterpField . SetDescription ( message ) ;
494+ if ( AvatarMetaField != null ) AvatarMetaField . SetDescription ( message ) ;
495+ }
496+
407497 private void SetAll ( string message )
408498 {
409499 if ( DebugField != null ) DebugField . SetDescription ( message ) ;
@@ -412,6 +502,7 @@ private void SetAll(string message)
412502 if ( RangesField != null ) RangesField . SetDescription ( message ) ;
413503 if ( BufferField != null ) BufferField . SetDescription ( message ) ;
414504 SetAudioDebugAll ( message ) ;
505+ SetAvatarDataDebugAll ( message ) ;
415506 }
416507 }
417508}
0 commit comments