Skip to content

Commit c09a3de

Browse files
fix: NetworkSceneManager add do not load during callback note in xml documentation [MTT-3495] (#1974)
* update xml documentation to be included in API documentation that one should not try to start a new scene event within a scene event notification callback. * update one more location just to make sure. * Update com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs Co-authored-by: Fatih Mar <[email protected]> Co-authored-by: Fatih Mar <[email protected]>
1 parent eaf781e commit c09a3de

File tree

2 files changed

+38
-18
lines changed

2 files changed

+38
-18
lines changed

com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace Unity.Netcode
1212
/// delegate type <see cref="NetworkSceneManager.SceneEventDelegate"/> uses this class to provide
1313
/// scene event status.<br/>
1414
/// <em>Note: This is only when <see cref="NetworkConfig.EnableSceneManagement"/> is enabled.</em><br/>
15+
/// <em>*** Do not start new scene events within scene event notification callbacks.</em><br/>
1516
/// See also: <br/>
1617
/// <seealso cref="SceneEventType"/>
1718
/// </summary>
@@ -166,6 +167,7 @@ public class NetworkSceneManager : IDisposable
166167
/// <item><term><see cref="OnUnloadComplete"/> Invoked only when an <see cref="SceneEventType.UnloadComplete"/> event is being processed</term></item>
167168
/// <item><term><see cref="OnSynchronizeComplete"/> Invoked only when a <see cref="SceneEventType.SynchronizeComplete"/> event is being processed</term></item>
168169
/// </list>
170+
/// <em>Note: Do not start new scene events within NetworkSceneManager scene event notification callbacks.</em><br/>
169171
/// </summary>
170172
public event SceneEventDelegate OnSceneEvent;
171173

@@ -239,13 +241,15 @@ public class NetworkSceneManager : IDisposable
239241

240242
/// <summary>
241243
/// Invoked when a <see cref="SceneEventType.Load"/> event is started by the server.<br/>
242-
/// <em>Note: The server and connected client(s) will always receive this notification.</em>
244+
/// <em>Note: The server and connected client(s) will always receive this notification.</em><br/>
245+
/// <em>*** Do not start new scene events within scene event notification callbacks.</em><br/>
243246
/// </summary>
244247
public event OnLoadDelegateHandler OnLoad;
245248

246249
/// <summary>
247250
/// Invoked when a <see cref="SceneEventType.Unload"/> event is started by the server.<br/>
248-
/// <em>Note: The server and connected client(s) will always receive this notification.</em>
251+
/// <em>Note: The server and connected client(s) will always receive this notification.</em><br/>
252+
/// <em>*** Do not start new scene events within scene event notification callbacks.</em><br/>
249253
/// </summary>
250254
public event OnUnloadDelegateHandler OnUnload;
251255

@@ -254,7 +258,8 @@ public class NetworkSceneManager : IDisposable
254258
/// after a client is approved for connection in order to synchronize the client with the currently loaded
255259
/// scenes and NetworkObjects. This event signifies the beginning of the synchronization event.<br/>
256260
/// <em>Note: The server and connected client(s) will always receive this notification.
257-
/// This event is generated on a per newly connected and approved client basis.</em>
261+
/// This event is generated on a per newly connected and approved client basis.</em><br/>
262+
/// <em>*** Do not start new scene events within scene event notification callbacks.</em><br/>
258263
/// </summary>
259264
public event OnSynchronizeDelegateHandler OnSynchronize;
260265

@@ -263,7 +268,8 @@ public class NetworkSceneManager : IDisposable
263268
/// This event signifies the end of an existing <see cref="SceneEventType.Load"/> event as it pertains
264269
/// to all clients connected when the event was started. This event signifies that all clients (and server) have
265270
/// finished the <see cref="SceneEventType.Load"/> event.<br/>
266-
/// <em>Note: this is useful to know when all clients have loaded the same scene (single or additive mode)</em>
271+
/// <em>Note: this is useful to know when all clients have loaded the same scene (single or additive mode)</em><br/>
272+
/// <em>*** Do not start new scene events within scene event notification callbacks.</em><br/>
267273
/// </summary>
268274
public event OnEventCompletedDelegateHandler OnLoadEventCompleted;
269275

@@ -273,21 +279,24 @@ public class NetworkSceneManager : IDisposable
273279
/// to all clients connected when the event was started. This event signifies that all clients (and server) have
274280
/// finished the <see cref="SceneEventType.Unload"/> event.<br/>
275281
/// <em>Note: this is useful to know when all clients have unloaded a specific scene. The <see cref="LoadSceneMode"/> will
276-
/// always be <see cref="LoadSceneMode.Additive"/> for this event.</em>
282+
/// always be <see cref="LoadSceneMode.Additive"/> for this event.</em><br/>
283+
/// <em>*** Do not start new scene events within scene event notification callbacks.</em><br/>
277284
/// </summary>
278285
public event OnEventCompletedDelegateHandler OnUnloadEventCompleted;
279286

280287
/// <summary>
281288
/// Invoked when a <see cref="SceneEventType.LoadComplete"/> event is generated by a client or server.<br/>
282289
/// <em>Note: The server receives this message from all clients (including itself).
283-
/// Each client receives their own notification sent to the server.</em>
290+
/// Each client receives their own notification sent to the server.</em><br/>
291+
/// <em>*** Do not start new scene events within scene event notification callbacks.</em><br/>
284292
/// </summary>
285293
public event OnLoadCompleteDelegateHandler OnLoadComplete;
286294

287295
/// <summary>
288296
/// Invoked when a <see cref="SceneEventType.UnloadComplete"/> event is generated by a client or server.<br/>
289297
/// <em>Note: The server receives this message from all clients (including itself).
290-
/// Each client receives their own notification sent to the server.</em>
298+
/// Each client receives their own notification sent to the server.</em><br/>
299+
/// <em>*** Do not start new scene events within scene event notification callbacks.</em><br/>
291300
/// </summary>
292301
public event OnUnloadCompleteDelegateHandler OnUnloadComplete;
293302

@@ -296,6 +305,7 @@ public class NetworkSceneManager : IDisposable
296305
/// <em> Note: The server receives this message from the client, but will never generate this event for itself.
297306
/// Each client receives their own notification sent to the server. This is useful to know that a client has
298307
/// completed the entire connection sequence, loaded all scenes, and synchronized all NetworkObjects.</em>
308+
/// <em>*** Do not start new scene events within scene event notification callbacks.</em><br/>
299309
/// </summary>
300310
public event OnSynchronizeCompleteDelegateHandler OnSynchronizeComplete;
301311

testproject/Assets/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.cs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -198,29 +198,40 @@ public IEnumerator Teardown()
198198
}
199199
}
200200

201+
private bool AllClientsSetCubeToPickupBackCube()
202+
{
203+
for (int setIndex = 0; setIndex < k_ClientInstanceCount; setIndex++)
204+
{
205+
if (m_Cube_NetObjs[setIndex + 1].parent != m_Pickup_Back_NetObjs[setIndex + 1])
206+
{
207+
return false;
208+
}
209+
210+
if (m_Cube_NetBhvs[setIndex + 1].ParentNetworkObject != m_Pickup_Back_NetObjs[setIndex + 1].GetComponent<NetworkObject>())
211+
{
212+
return false;
213+
}
214+
}
215+
216+
return true;
217+
}
218+
201219
[UnityTest]
202220
public IEnumerator SetParentDirect()
203221
{
204-
var waitForNetworkTick = new WaitForSeconds(1.0f / m_ServerNetworkManager.NetworkConfig.TickRate);
222+
var timeoutHelper = new TimeoutHelper();
205223
// Server: Set/Cube -> Set/Pickup/Back/Cube
206224
m_Cube_NetObjs[0].parent = m_Pickup_Back_NetObjs[0];
207225
Assert.That(m_Cube_NetBhvs[0].ParentNetworkObject, Is.EqualTo(m_Pickup_Back_NetObjs[0].GetComponent<NetworkObject>()));
208226

209-
yield return waitForNetworkTick;
210-
211227
// Client[n]: Set/Cube -> Set/Pickup/Back/Cube
212-
for (int setIndex = 0; setIndex < k_ClientInstanceCount; setIndex++)
213-
{
214-
Assert.That(m_Cube_NetObjs[setIndex + 1].parent, Is.EqualTo(m_Pickup_Back_NetObjs[setIndex + 1]));
215-
Assert.That(m_Cube_NetBhvs[setIndex + 1].ParentNetworkObject, Is.EqualTo(m_Pickup_Back_NetObjs[setIndex + 1].GetComponent<NetworkObject>()));
216-
}
228+
yield return NetcodeIntegrationTest.WaitForConditionOrTimeOut(AllClientsSetCubeToPickupBackCube, timeoutHelper);
229+
Assert.False(timeoutHelper.TimedOut, "TImed out waiting for Client[n]: Set/Cube -> Set/Pickup/Back/Cube");
217230

218231
// Server: Set/Pickup/Back -> Root/Cube
219232
m_Cube_NetObjs[0].parent = null;
220233
Assert.That(m_Cube_NetBhvs[0].ParentNetworkObject, Is.EqualTo(null));
221234

222-
yield return waitForNetworkTick;
223-
224235
bool CheckClientSideCubeForNull()
225236
{
226237
// Client[n]: Set/Pickup/Back -> Root/Cube
@@ -233,7 +244,6 @@ bool CheckClientSideCubeForNull()
233244
}
234245
return true;
235246
}
236-
var timeoutHelper = new TimeoutHelper();
237247
yield return NetcodeIntegrationTest.WaitForConditionOrTimeOut(CheckClientSideCubeForNull, timeoutHelper);
238248
Assert.False(timeoutHelper.TimedOut, $"Timed out waiting for client parent to be null!");
239249

0 commit comments

Comments
 (0)