55using Unity . NetCode . Analytics ;
66using Unity . Networking . Transport ;
77using UnityEditor ;
8+ using UnityEditor . PackageManager ;
89using UnityEngine . Analytics ;
910
1011namespace Unity . NetCode . Editor
@@ -40,14 +41,12 @@ static GhostScaleAnalyticsData ComputeScaleData()
4041 {
4142 var data = new GhostScaleAnalyticsData
4243 {
43- PlayerCount = NetCodeAnalyticsState . GetPlayerCount ( ) ,
4444 Settings = new PlaymodeSettings
4545 {
4646 ThinClientCount = MultiplayerPlayModePreferences . RequestedNumThinClients ,
4747 SimulatorEnabled = MultiplayerPlayModePreferences . SimulatorEnabled ,
4848 Delay = MultiplayerPlayModePreferences . PacketDelayMs ,
4949 DropPercentage = MultiplayerPlayModePreferences . PacketDropPercentage ,
50- FuzzPercentage = MultiplayerPlayModePreferences . PacketFuzzPercentage ,
5150 Jitter = MultiplayerPlayModePreferences . PacketJitterMs ,
5251 PlayModeType = MultiplayerPlayModePreferences . RequestedPlayType . ToString ( ) ,
5352 SimulatorPreset = MultiplayerPlayModePreferences . CurrentNetworkSimulatorPreset
@@ -62,39 +61,6 @@ static GhostScaleAnalyticsData ComputeScaleData()
6261 var numServerWorlds = 0 ;
6362 foreach ( var world in World . All )
6463 {
65- void CollectMainClientData ( )
66- {
67- TryGetSingleton ( world , out data . ClientTickRate ) ;
68- data . MainClientData . NumOfSpawnedGhost = CountSpawnedGhosts ( world . EntityManager ) ;
69- TryGetSingleton ( world , out data . ClientServerTickRate ) ;
70-
71- var spawnedGhostCount = CountSpawnedGhosts ( world . EntityManager ) ;
72- TryGetSingleton < GhostRelevancy > ( world , out var ghostRelevancy ) ;
73- using var predictedGhostQuery = world . EntityManager . CreateEntityQuery ( ComponentType . ReadOnly < PredictedGhost > ( ) ) ;
74- var predictionCount = predictedGhostQuery . CalculateEntityCountWithoutFiltering ( ) ;
75- TryGetSingleton < PredictionSwitchingAnalyticsData > ( world , out var predictionSwitchingAnalyticsData ) ;
76- data . MainClientData = new MainClientData
77- {
78- RelevancyMode = ghostRelevancy . GhostRelevancyMode ,
79- NumOfSpawnedGhost = spawnedGhostCount ,
80- NumOfPredictedGhosts = predictionCount ,
81- NumSwitchToInterpolated = predictionSwitchingAnalyticsData . NumTimesSwitchedToInterpolated ,
82- NumSwitchToPredicted = predictionSwitchingAnalyticsData . NumTimesSwitchedToPredicted ,
83- } ;
84- }
85-
86- void CollectServerData ( )
87- {
88- data . ServerSpawnedGhostCount = CountSpawnedGhosts ( world . EntityManager ) ;
89-
90- data . GhostTypes = CollectGhostTypes ( world . EntityManager ) ;
91- data . GhostTypeCount = data . GhostTypes . Length ;
92-
93- data . SnapshotTargetSize = TryGetSingleton < NetworkStreamSnapshotTargetSize > ( world , out var snapshotTargetSize )
94- ? snapshotTargetSize . Value
95- : NetworkParameterConstants . MaxMessageSize ;
96- }
97-
9864 var sent = NetCodeAnalyticsState . GetUpdateLength ( world ) ;
9965 if ( sent > 0 )
10066 {
@@ -118,6 +84,47 @@ void CollectServerData()
11884 }
11985 numMainClientWorlds ++ ;
12086 }
87+
88+ continue ;
89+
90+ void CollectServerData ( )
91+ {
92+ data . ServerSpawnedGhostCount = CountSpawnedGhosts ( world . EntityManager ) ;
93+
94+ data . GhostTypes = CollectGhostTypes ( world . EntityManager ) ;
95+ data . GhostTypeCount = data . GhostTypes . Length ;
96+
97+ data . SnapshotTargetSize = TryGetSingleton < NetworkStreamSnapshotTargetSize > ( world , out var snapshotTargetSize )
98+ ? snapshotTargetSize . Value
99+ : NetworkParameterConstants . MaxMessageSize ;
100+ }
101+
102+ void CollectMainClientData ( )
103+ {
104+ if ( TryGetSingleton ( world , out ClientTickRate clientTickRate ) )
105+ {
106+ data . ClientTickRate = new WrappedClientTickRate ( clientTickRate ) ;
107+ }
108+ data . MainClientData . NumOfSpawnedGhost = CountSpawnedGhosts ( world . EntityManager ) ;
109+ if ( TryGetSingleton ( world , out ClientServerTickRate clientServerTickRate ) )
110+ {
111+ data . ClientServerTickRate = new WrappedClientServerTickRate ( clientServerTickRate ) ;
112+ }
113+
114+ var spawnedGhostCount = CountSpawnedGhosts ( world . EntityManager ) ;
115+ TryGetSingleton < GhostRelevancy > ( world , out var ghostRelevancy ) ;
116+ using var predictedGhostQuery = world . EntityManager . CreateEntityQuery ( ComponentType . ReadOnly < PredictedGhost > ( ) ) ;
117+ var predictionCount = predictedGhostQuery . CalculateEntityCountWithoutFiltering ( ) ;
118+ TryGetSingleton < PredictionSwitchingAnalyticsData > ( world , out var predictionSwitchingAnalyticsData ) ;
119+ data . MainClientData = new MainClientData
120+ {
121+ RelevancyMode = ( int ) ghostRelevancy . GhostRelevancyMode ,
122+ NumOfSpawnedGhost = spawnedGhostCount ,
123+ NumOfPredictedGhosts = predictionCount ,
124+ NumSwitchToInterpolated = ( int ) predictionSwitchingAnalyticsData . NumTimesSwitchedToInterpolated ,
125+ NumSwitchToPredicted = ( int ) predictionSwitchingAnalyticsData . NumTimesSwitchedToPredicted ,
126+ } ;
127+ }
121128 }
122129
123130 if ( amount == 0 )
@@ -126,7 +133,7 @@ void CollectServerData()
126133 }
127134 else
128135 {
129- data . AverageGhostInSnapshot = serializedSent / amount ;
136+ data . AverageGhostInSnapshot = ( int ) ( serializedSent / amount ) ;
130137 }
131138 data . NumMainClientWorlds = numMainClientWorlds ;
132139 data . NumServerWorlds = numServerWorlds ;
@@ -211,6 +218,74 @@ public override string ToString()
211218 }
212219 }
213220
221+ /// <summary>
222+ /// This struct is used to wrap the <see cref="ClientServerTickRate"/> struct to be serializable.
223+ /// We ensure here that the data matches the expected format for the analytics.
224+ /// If you change this struct, you must also update the analytics event in schemata.
225+ /// </summary>
226+ [ Serializable ]
227+ internal struct WrappedClientServerTickRate
228+ {
229+ public int MaxSimulationStepBatchSize ;
230+ public int MaxSimulationStepsPerFrame ;
231+ public int NetworkTickRate ;
232+ public int SimulationTickRate ;
233+ public int TargetFrameRateMode ;
234+
235+ public WrappedClientServerTickRate ( ClientServerTickRate clientServerTickRate )
236+ {
237+ this . MaxSimulationStepBatchSize = clientServerTickRate . MaxSimulationStepBatchSize ;
238+ this . MaxSimulationStepsPerFrame = clientServerTickRate . MaxSimulationStepsPerFrame ;
239+ this . NetworkTickRate = clientServerTickRate . NetworkTickRate ;
240+ this . SimulationTickRate = clientServerTickRate . SimulationTickRate ;
241+ this . TargetFrameRateMode = ( int ) clientServerTickRate . TargetFrameRateMode ;
242+ }
243+ }
244+
245+ /// <summary>
246+ /// This struct is used to wrap the <see cref="ClientTickRate"/> struct to be serializable.
247+ /// We ensure here that the data matches the expected format for the analytics.
248+ /// If you change this struct, you must also update the analytics event in schemata.
249+ /// </summary>
250+ [ Serializable ]
251+ internal struct WrappedClientTickRate
252+ {
253+ public int CommandAgeCorrectionFraction ;
254+ public int InterpolationDelayCorrectionFraction ;
255+ public int InterpolationDelayJitterScale ;
256+ public int InterpolationDelayMaxDeltaTicksFraction ;
257+ public int InterpolationTimeMS ;
258+ public int InterpolationTimeNetTicks ;
259+ public int InterpolationTimeScaleMax ;
260+ public int InterpolationTimeScaleMin ;
261+ public int MaxExtrapolationTimeSimTicks ;
262+ public int MaxPredictAheadTimeMS ;
263+ public int MaxPredictionStepBatchSizeFirstTimeTick ;
264+ public int MaxPredictionStepBatchSizeRepeatedTick ;
265+ public int PredictionTimeScaleMax ;
266+ public int PredictionTimeScaleMin ;
267+ public int TargetCommandSlack ;
268+
269+ public WrappedClientTickRate ( ClientTickRate clientTickRate )
270+ {
271+ this . CommandAgeCorrectionFraction = ( int ) clientTickRate . CommandAgeCorrectionFraction ;
272+ this . InterpolationDelayCorrectionFraction = ( int ) clientTickRate . InterpolationDelayCorrectionFraction ;
273+ this . InterpolationDelayJitterScale = ( int ) clientTickRate . InterpolationDelayJitterScale ;
274+ this . InterpolationDelayMaxDeltaTicksFraction = ( int ) clientTickRate . InterpolationDelayMaxDeltaTicksFraction ;
275+ this . InterpolationTimeMS = ( int ) clientTickRate . InterpolationTimeMS ;
276+ this . InterpolationTimeNetTicks = ( int ) clientTickRate . InterpolationTimeNetTicks ;
277+ this . InterpolationTimeScaleMax = ( int ) clientTickRate . InterpolationTimeScaleMax ;
278+ this . InterpolationTimeScaleMin = ( int ) clientTickRate . InterpolationTimeScaleMin ;
279+ this . MaxExtrapolationTimeSimTicks = ( int ) clientTickRate . MaxExtrapolationTimeSimTicks ;
280+ this . MaxPredictAheadTimeMS = ( int ) clientTickRate . MaxPredictAheadTimeMS ;
281+ this . MaxPredictionStepBatchSizeFirstTimeTick = clientTickRate . MaxPredictionStepBatchSizeFirstTimeTick ;
282+ this . MaxPredictionStepBatchSizeRepeatedTick = clientTickRate . MaxPredictionStepBatchSizeRepeatedTick ;
283+ this . PredictionTimeScaleMax = ( int ) clientTickRate . PredictionTimeScaleMax ;
284+ this . PredictionTimeScaleMin = ( int ) clientTickRate . PredictionTimeScaleMin ;
285+ this . TargetCommandSlack = ( int ) clientTickRate . TargetCommandSlack ;
286+ }
287+ }
288+
214289 [ Serializable ]
215290#if UNITY_2023_2_OR_NEWER
216291 struct GhostScaleAnalyticsData : IAnalytic . IData
@@ -219,13 +294,12 @@ struct GhostScaleAnalyticsData
219294#endif
220295 {
221296 public PlaymodeSettings Settings ;
222- public int PlayerCount ;
223297 public int ServerSpawnedGhostCount ;
224298 public int GhostTypeCount ;
225- public uint AverageGhostInSnapshot ;
299+ public int AverageGhostInSnapshot ;
226300 public GhostTypeData [ ] GhostTypes ;
227- public ClientServerTickRate ClientServerTickRate ;
228- public ClientTickRate ClientTickRate ;
301+ public WrappedClientServerTickRate ClientServerTickRate ;
302+ public WrappedClientTickRate ClientTickRate ;
229303 public MainClientData MainClientData ;
230304 public int SnapshotTargetSize ;
231305 public int NumMainClientWorlds ;
@@ -235,7 +309,6 @@ public override string ToString()
235309 {
236310 var builder = new StringBuilder ( ) ;
237311 builder . Append ( $ "{ nameof ( Settings ) } : { Settings } , " +
238- $ "{ nameof ( PlayerCount ) } : { PlayerCount } , " +
239312 $ "{ nameof ( ServerSpawnedGhostCount ) } : { ServerSpawnedGhostCount } , " +
240313 $ "{ nameof ( GhostTypeCount ) } : { GhostTypeCount } , " +
241314 $ "{ nameof ( AverageGhostInSnapshot ) } : { AverageGhostInSnapshot } , " +
@@ -259,10 +332,10 @@ public override string ToString()
259332 [ Serializable ]
260333 struct MainClientData
261334 {
262- public GhostRelevancyMode RelevancyMode ;
335+ public int RelevancyMode ;
263336 public int NumOfPredictedGhosts ;
264- public long NumSwitchToPredicted ;
265- public long NumSwitchToInterpolated ;
337+ public int NumSwitchToPredicted ;
338+ public int NumSwitchToInterpolated ;
266339 public int NumOfSpawnedGhost ;
267340
268341 public override string ToString ( )
@@ -282,7 +355,6 @@ struct PlaymodeSettings
282355 public bool SimulatorEnabled ;
283356 public int Delay ;
284357 public int DropPercentage ;
285- public int FuzzPercentage ;
286358 public int Jitter ;
287359 public string PlayModeType ;
288360 public string SimulatorPreset ;
@@ -293,7 +365,6 @@ public override string ToString()
293365 $ "{ nameof ( SimulatorEnabled ) } : { SimulatorEnabled } , " +
294366 $ "{ nameof ( Delay ) } : { Delay } , " +
295367 $ "{ nameof ( DropPercentage ) } : { DropPercentage } , " +
296- $ "{ nameof ( FuzzPercentage ) } : { FuzzPercentage } , " +
297368 $ "{ nameof ( Jitter ) } : { Jitter } , " +
298369 $ "{ nameof ( PlayModeType ) } : { PlayModeType } , " +
299370 $ "{ nameof ( SimulatorPreset ) } : { SimulatorPreset } , ";
@@ -306,7 +377,7 @@ static class GhostComponentAnalytics
306377 public const int k_MaxItems = 1000 ;
307378 public const string k_VendorKey = "unity.netcode" ;
308379 public const string k_Scale = "NetcodeGhostComponentScale" ;
309- public const int k_ScaleVersion = 2 ;
380+ public const int k_ScaleVersion = 3 ;
310381 public const int k_ConfigurationVersion = 1 ;
311382 public const string k_Configuration = "NetcodeGhostComponentConfiguration" ;
312383
0 commit comments