@@ -167,6 +167,53 @@ public static implicit operator ConnectionAddressData(NetworkEndPoint d) =>
167167
168168 public ConnectionAddressData ConnectionData = s_DefaultConnectionAddressData ;
169169
170+ [ Serializable ]
171+ public struct SimulatorParameters
172+ {
173+ [ Tooltip ( "Delay to add to every send and received packet (in milliseconds). Only applies in the editor " +
174+ "and in development builds. The value is ignored in production builds." ) ]
175+ [ SerializeField ] public int PacketDelayMS ;
176+
177+ [ Tooltip ( "Jitter (random variation) to add/substract to the packet delay (in milliseconds). Only " +
178+ "applies in the editor and in development builds. The value is ignored in production builds." ) ]
179+ [ SerializeField ] public int PacketJitterMS ;
180+
181+ [ Tooltip ( "Percentage of sent and received packets to drop. Only applies in the editor and in the editor " +
182+ "and in developments builds." ) ]
183+ [ SerializeField ] public int PacketDropRate ;
184+ }
185+
186+ public SimulatorParameters DebugSimulator = new SimulatorParameters
187+ {
188+ PacketDelayMS = 0 ,
189+ PacketJitterMS = 0 ,
190+ PacketDropRate = 0
191+ } ;
192+
193+ // Only for backward compatibility with how we used to handle simulator parameters.
194+ #if DEVELOPMENT_BUILD
195+ [ Obsolete ( "Use SetDebugSimulatorParameters() instead." ) ]
196+ public int ClientPacketDelayMs
197+ {
198+ get => DebugSimulator . PacketDelayMS ;
199+ set => DebugSimulator . PacketDelayMS = value ;
200+ }
201+
202+ [ Obsolete ( "Use SetDebugSimulatorParameters() instead." ) ]
203+ public int ClientPacketJitterMs
204+ {
205+ get => DebugSimulator . PacketJitterMS ;
206+ set => DebugSimulator . PacketJitterMS = value ;
207+ }
208+
209+ [ Obsolete ( "Use SetDebugSimulatorParameters() instead." ) ]
210+ public int ClientPacketDropRate
211+ {
212+ get => DebugSimulator . PacketDropRate ;
213+ set => DebugSimulator . PacketDropRate = value ;
214+ }
215+ #endif
216+
170217 private State m_State = State . Disconnected ;
171218 private NetworkDriver m_Driver ;
172219 private NetworkSettings m_NetworkSettings ;
@@ -184,43 +231,6 @@ public static implicit operator ConnectionAddressData(NetworkEndPoint d) =>
184231
185232 internal NetworkManager NetworkManager ;
186233
187- #if UNITY_EDITOR
188- private static int ClientPacketDelayMs => UnityEditor . EditorPrefs . GetInt ( $ "NetcodeGameObjects_{ Application . productName } _ClientDelay") ;
189- private static int ClientPacketJitterMs => UnityEditor . EditorPrefs . GetInt ( $ "NetcodeGameObjects_{ Application . productName } _ClientJitter") ;
190- private static int ClientPacketDropRate => UnityEditor . EditorPrefs . GetInt ( $ "NetcodeGameObjects_{ Application . productName } _ClientDropRate") ;
191- #elif DEVELOPMENT_BUILD
192- public static int ClientPacketDelayMs = 0 ;
193- public static int ClientPacketJitterMs = 0 ;
194- public static int ClientPacketDropRate = 0 ;
195- #endif
196- #if UNITY_EDITOR || DEVELOPMENT_BUILD
197- public SimulatorUtility . Parameters ClientSimulatorParameters
198- {
199- get
200- {
201- var packetDelay = ClientPacketDelayMs ;
202- var jitter = ClientPacketJitterMs ;
203- if ( jitter > packetDelay )
204- {
205- jitter = packetDelay ;
206- }
207-
208- var packetDrop = ClientPacketDropRate ;
209- int networkRate = 60 ; // TODO: read from some better place
210- // All 3 packet types every frame stored for maximum delay, doubled for safety margin
211- int maxPackets = 2 * ( networkRate * 3 * packetDelay + 999 ) / 1000 ;
212- return new SimulatorUtility . Parameters
213- {
214- MaxPacketSize = NetworkParameterConstants . MTU ,
215- MaxPacketCount = maxPackets ,
216- PacketDelayMs = packetDelay ,
217- PacketJitterMs = jitter ,
218- PacketDropPercentage = packetDrop
219- } ;
220- }
221- }
222- #endif
223-
224234 /// <summary>
225235 /// SendQueue dictionary is used to batch events instead of sending them immediately.
226236 /// </summary>
@@ -478,6 +488,26 @@ public void SetConnectionData(NetworkEndPoint endPoint, NetworkEndPoint listenEn
478488 SetConnectionData ( serverAddress , endPoint . Port , listenAddress ) ;
479489 }
480490
491+ /// <summary>Set the parameters for the debug simulator.</summary>
492+ /// <param name="packetDelay">Packet delay in milliseconds.</param>
493+ /// <param name="packetJitter">Packet jitter in milliseconds.</param>
494+ /// <param name="dropRate">Packet drop percentage.</param>
495+ public void SetDebugSimulatorParameters ( int packetDelay , int packetJitter , int dropRate )
496+ {
497+ if ( m_Driver . IsCreated )
498+ {
499+ Debug . LogError ( "SetDebugSimulatorParameters() must be called before StartClient() or StartServer()." ) ;
500+ return ;
501+ }
502+
503+ DebugSimulator = new SimulatorParameters
504+ {
505+ PacketDelayMS = packetDelay ,
506+ PacketJitterMS = packetJitter ,
507+ PacketDropRate = dropRate
508+ } ;
509+ }
510+
481511 private bool StartRelayServer ( )
482512 {
483513 //This comparison is currently slow since RelayServerData does not implement a custom comparison operator that doesn't use
@@ -974,6 +1004,28 @@ public override void Shutdown()
9741004 m_ServerClientId = 0 ;
9751005 }
9761006
1007+ private void ConfigureSimulator ( )
1008+ {
1009+ #if UNITY_EDITOR
1010+ // Backward-compatibility with how we used to handle simulator parameters.
1011+ var packetDelay = UnityEditor . EditorPrefs . GetInt ( $ "NetcodeGameObjects_{ Application . productName } _ClientDelay", DebugSimulator . PacketDelayMS ) ;
1012+ var packetJitter = UnityEditor . EditorPrefs . GetInt ( $ "NetcodeGameObjects_{ Application . productName } _ClientJitter", DebugSimulator . PacketJitterMS ) ;
1013+ var dropRate = UnityEditor . EditorPrefs . GetInt ( $ "NetcodeGameObjects_{ Application . productName } _ClientDropRate", DebugSimulator . PacketDropRate ) ;
1014+ #else
1015+ var packetDelay = DebugSimulator . PacketDelayMS ;
1016+ var packetJitter = DebugSimulator . PacketJitterMS ;
1017+ var dropRate = DebugSimulator . PacketDropRate ;
1018+ #endif
1019+
1020+ m_NetworkSettings . WithSimulatorStageParameters (
1021+ maxPacketCount : 300 , // TODO Is there any way to compute a better value?
1022+ maxPacketSize : NetworkParameterConstants . MTU ,
1023+ packetDelayMs : packetDelay ,
1024+ packetJitterMs : packetJitter ,
1025+ packetDropPercentage : dropRate
1026+ ) ;
1027+ }
1028+
9771029 public void CreateDriver ( UnityTransport transport , out NetworkDriver driver ,
9781030 out NetworkPipeline unreliableFragmentedPipeline ,
9791031 out NetworkPipeline unreliableSequencedFragmentedPipeline ,
@@ -986,11 +1038,9 @@ public void CreateDriver(UnityTransport transport, out NetworkDriver driver,
9861038
9871039#if UNITY_EDITOR || DEVELOPMENT_BUILD
9881040 maxFrameTimeMS = 100 ;
989-
990- var simulatorParams = ClientSimulatorParameters ;
991-
992- m_NetworkSettings . AddRawParameterStruct ( ref simulatorParams ) ;
1041+ ConfigureSimulator ( ) ;
9931042#endif
1043+
9941044 m_NetworkSettings . WithNetworkConfigParameters (
9951045 maxConnectAttempts : transport . m_MaxConnectAttempts ,
9961046 connectTimeoutMS : transport . m_ConnectTimeoutMS ,
@@ -999,8 +1049,9 @@ public void CreateDriver(UnityTransport transport, out NetworkDriver driver,
9991049 maxFrameTimeMS : maxFrameTimeMS ) ;
10001050
10011051 driver = NetworkDriver . Create ( m_NetworkSettings ) ;
1052+
10021053#if UNITY_EDITOR || DEVELOPMENT_BUILD
1003- if ( simulatorParams . PacketDelayMs > 0 || simulatorParams . PacketDropInterval > 0 )
1054+ if ( DebugSimulator . PacketDelayMS > 0 || DebugSimulator . PacketDropRate > 0 )
10041055 {
10051056 unreliableFragmentedPipeline = driver . CreatePipeline (
10061057 typeof ( FragmentationPipelineStage ) ,
0 commit comments