Skip to content

Commit 7346a2f

Browse files
fix: ServerDestroySpawnedSceneObjects throws an exception before switching scene (#618)
* fix: crash during scene transition If you have in-scene placed NetworkObjects and you transition to a new scene then a crash will occur in NetworkSpawnManager.ServerDestroySpawnedSceneObjects due to NetworkObjects being removed from the SpawnedObjectsList during the "OnDestroy" invocation. This fixes that crash. * style: comments and standards Adding some comments as to why the code is added, camelCase for locals, and generic Var as opposed to specific type for declaration. * refactor: comments and better approach This applies a better approach to the issue of removing objects from a list that is being iterated over without throwing the "Collection was modified; enumeration operation may not execute" exception due to NetworkObjects removing themselves from the SpawnedObjectList during OnDestroy. * refactor: comment Minor tweak to the comment as to why the code was added.
1 parent 28f81d6 commit 7346a2f

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

com.unity.multiplayer.mlapi/Runtime/Spawning/NetworkSpawnManager.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,19 +541,28 @@ internal static void ServerResetShudownStateForSceneObjects()
541541
}
542542
}
543543

544+
/// <summary>
545+
/// Gets called only by NetworkSceneManager.SwitchScene
546+
/// </summary>
544547
internal static void ServerDestroySpawnedSceneObjects()
545548
{
546-
foreach (var sobj in SpawnedObjectsList)
549+
//This Allocation is "ok" for now because this code only executes when a new scene is switched to
550+
//We need to create a new copy the HashSet of NetworkObjects (SpawnedObjectsList) so we can remove
551+
//objects from the HashSet (SpawnedObjectsList) without causing a list has been modified exception to occur.
552+
var spawnedObjects = SpawnedObjectsList.ToList();
553+
foreach (var sobj in spawnedObjects)
547554
{
548555
if ((sobj.IsSceneObject != null && sobj.IsSceneObject == true) || sobj.DestroyWithScene)
549556
{
550557
if (CustomDestroyHandlers.ContainsKey(sobj.PrefabHash))
551558
{
559+
SpawnedObjectsList.Remove(sobj);
552560
CustomDestroyHandlers[sobj.PrefabHash](sobj);
553561
OnDestroyObject(sobj.NetworkObjectId, false);
554562
}
555563
else
556564
{
565+
SpawnedObjectsList.Remove(sobj);
557566
MonoBehaviour.Destroy(sobj.gameObject);
558567
}
559568
}

0 commit comments

Comments
 (0)