diff --git a/Assets/Mirage/Runtime/ServerObjectManager.cs b/Assets/Mirage/Runtime/ServerObjectManager.cs
index 2e42b46279..7eb156cb43 100644
--- a/Assets/Mirage/Runtime/ServerObjectManager.cs
+++ b/Assets/Mirage/Runtime/ServerObjectManager.cs
@@ -23,10 +23,10 @@ namespace Mirage
public class ServerObjectManager : MonoBehaviour
{
private static readonly ILogger logger = LogFactory.GetLogger(typeof(ServerObjectManager));
- ///
- /// HashSet for NetworkIdentity that can be re-used without allocation
- ///
- private static HashSet _setCache = new HashSet();
+ /// HashSet for NetworkIdentity that can be re-used without allocation
+ private static HashSet _skipCache = new HashSet();
+ /// HashSet for NetworkIdentity that can be re-used without allocation
+ private static List _spawnCache = new List();
internal RpcHandler _rpcHandler;
@@ -136,7 +136,7 @@ public void ReplaceCharacter(INetworkPlayer player, NetworkIdentity identity, bo
}
if (!player.HasCharacter)
{
- throw new InvalidOperationException($"ReplaceCharacter can only be called if Player already has a charater");
+ throw new InvalidOperationException($"ReplaceCharacter can only be called if Player already has a character");
}
//NOTE: there can be an existing player
@@ -247,8 +247,8 @@ private void Respawn(NetworkIdentity identity)
///
internal void ShowToPlayer(NetworkIdentity identity, INetworkPlayer player)
{
- var visiblity = identity.Visibility;
- if (visiblity is NetworkVisibility networkVisibility)
+ var visibility = identity.Visibility;
+ if (visibility is NetworkVisibility networkVisibility)
networkVisibility.InvokeVisibilityChanged(player, true);
// dont send if loading scene
@@ -627,16 +627,16 @@ public void SpawnVisibleObjects(INetworkPlayer player, NetworkIdentity skip)
/// NetworkIdentity to skip when spawning. Can be null
public void SpawnVisibleObjects(INetworkPlayer player, bool ignoreHasCharacter, NetworkIdentity skip)
{
- _setCache.Clear();
- _setCache.Add(skip);
- SpawnVisibleObjects(player, ignoreHasCharacter, _setCache);
+ _skipCache.Clear();
+ _skipCache.Add(skip);
+ SpawnVisibleObjects(player, ignoreHasCharacter, _skipCache);
}
///
/// Sends spawn message for scene objects and other visible objects to the given player if it has a character
///
/// The player to spawn objects for
- /// If true will spawn visibile objects even if player does not have a spawned character yet
+ /// If true will spawn visible objects even if player does not have a spawned character yet
/// NetworkIdentity to skip when spawning. Can be null
public void SpawnVisibleObjects(INetworkPlayer player, bool ignoreHasCharacter, HashSet skip)
{
@@ -658,11 +658,14 @@ public void SpawnVisibleObjects(INetworkPlayer player, bool ignoreHasCharacter,
if (logger.LogEnabled()) logger.Log($"SpawnVisibleObjects: Checking Observers on {_server.World.SpawnedIdentities.Count} objects for player: {player}");
+ // add to cache first, so SpawnedIdentities can be modified inside loop without throwing
+ _spawnCache.Clear();
+ _spawnCache.AddRange(_server.World.SpawnedIdentities);
// add connection to each nearby NetworkIdentity's observers, which
// internally sends a spawn message for each one to the connection.
- foreach (var identity in _server.World.SpawnedIdentities)
+ foreach (var identity in _spawnCache)
{
- // allow for skips so that addChatacter doesn't send 2 spawn message for existing object
+ // allow for skips so that addCharacter doesn't send 2 spawn message for existing object
if (skip != null && skip.Contains(identity))
continue;
@@ -678,6 +681,8 @@ public void SpawnVisibleObjects(INetworkPlayer player, bool ignoreHasCharacter,
}
}
}
+
+ _spawnCache.Clear();
}
private sealed class NetworkIdentityComparer : IComparer