Skip to content

Commit 352db12

Browse files
fix: observers not being cleared on despawning NetworkObject (#2009)
1 parent 1c4f3ef commit 352db12

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
2020
### Removed
2121

2222
### Fixed
23-
23+
- Fixed issue where `NetworkObject.Observers` was not being cleared when despawned. (#2009)
2424
- Fixed `NetworkAnimator` could not run in the server authoritative mode. (#2003)
2525
- Fixed issue where late joining clients would get a soft synchronization error if any in-scene placed NetworkObjects were parented under another `NetworkObject`. (#1985)
2626
- Fixed issue where `NetworkBehaviourReference` would throw a type cast exception if using `NetworkBehaviourReference.TryGet` and the component type was not found. (#1984)

com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,9 @@ internal void OnDespawnObject(NetworkObject networkObject, bool destroyGameObjec
811811
SpawnedObjectsList.Remove(networkObject);
812812
}
813813

814+
// Always clear out the observers list when despawned
815+
networkObject.Observers.Clear();
816+
814817
var gobj = networkObject.gameObject;
815818
if (destroyGameObject && gobj != null)
816819
{

testproject/Assets/Tests/Runtime/RpcObserverTests.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,51 @@ private IEnumerator RunRpcObserverTest(List<ulong> nonObservers)
140140
}
141141
}
142142

143+
/// <summary>
144+
/// Validates that when a NetworkObject is despawned but not destroyed
145+
/// and then re-spawned that the observer list is cleared
146+
/// </summary>
147+
[UnityTest]
148+
public IEnumerator DespawnRespawnObserverTest()
149+
{
150+
var nonObservers = new List<ulong>();
151+
m_ServerRpcObserverObject.ResetTest();
152+
// Wait for all clients to report they have spawned an instance of our test prefab
153+
yield return WaitForConditionOrTimeOut(m_ServerRpcObserverObject.AllClientsSpawned);
154+
155+
m_ServerRpcObserverObject.ObserverMessageClientRpc();
156+
157+
yield return WaitForConditionOrTimeOut(m_ServerRpcObserverObject.AllObserversReceivedRPC);
158+
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for all clients to receive message!\n" +
159+
$"Clients that received the message:{m_ServerRpcObserverObject.GetClientIdsAsString()}");
160+
Assert.False(m_ServerRpcObserverObject.NonObserversReceivedRPC(nonObservers), $"Non-observers ({m_ServerRpcObserverObject.GetClientIdsAsString(nonObservers)}) received the RPC message!");
161+
162+
m_ServerRpcObserverObject.NetworkObject.Despawn(false);
163+
164+
Assert.True(m_ServerRpcObserverObject.NetworkObject.Observers.Count == 0, $"Despawned {m_ServerRpcObserverObject.name} but it still has {m_ServerRpcObserverObject.NetworkObject.Observers.Count} observers!");
165+
166+
for (int i = 4; i < NumberOfClients; i++)
167+
{
168+
nonObservers.Add(m_ClientNetworkManagers[i].LocalClientId);
169+
m_ServerNetworkManager.DisconnectClient(m_ClientNetworkManagers[i].LocalClientId);
170+
}
171+
172+
yield return s_DefaultWaitForTick;
173+
m_ServerRpcObserverObject.ResetTest();
174+
m_ServerRpcObserverObject.NetworkObject.Spawn();
175+
m_ServerRpcObserverObject.ObserverMessageClientRpc();
176+
yield return WaitForConditionOrTimeOut(m_ServerRpcObserverObject.AllObserversReceivedRPC);
177+
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for all clients to receive message!\n" +
178+
$"Clients that received the message:{m_ServerRpcObserverObject.GetClientIdsAsString()}");
179+
Assert.False(m_ServerRpcObserverObject.NonObserversReceivedRPC(nonObservers), $"Non-observers ({m_ServerRpcObserverObject.GetClientIdsAsString(nonObservers)}) received the RPC message!");
180+
181+
// Always verify the host received the RPC
182+
if (m_UseHost)
183+
{
184+
Assert.True(m_ServerRpcObserverObject.HostReceivedMessage, $"Host failed to receive the ClientRpc with the following observers: {m_ServerRpcObserverObject.GetClientIdsAsString()}!");
185+
}
186+
}
187+
143188
protected override IEnumerator OnTearDown()
144189
{
145190
// Make sure to dispose of the native array

0 commit comments

Comments
 (0)