Skip to content

Commit 429b256

Browse files
fix: Objects without observers are DestroyWithOwner (#3342)
<!-- Replace this block with what this PR does and why. Describe what you'd like reviewers to know, how you applied the engineering principles, and any interesting tradeoffs made. Delete bullet points below that don't apply, and update the changelog section as appropriate. --> - Ensure objects with no observers (or only current owner as observer) are treated as if `DontDestroyWithOwner = true` on client disconnect - Explicitly check if childObject has new client as observer on client connect <!-- Add short version of the JIRA ticket to the PR title (e.g. "feat: new shiny feature [MTT-123]") --> [MTTB-1041](https://jira.unity3d.com/browse/MTTB-1041) Changelog for this is in #3323. <!-- Add RFC link here if applicable. --> ## Changelog - Fixed: Ensure objects with no observers are treated as if `DontDestroyWithOwner = true` on client disconnect ## Testing and Documentation - No tests have been added. <!-- Uncomment and mark items off with a * if this PR deprecates any API: ### Deprecated API - [ ] An `[Obsolete]` attribute was added along with a `(RemovedAfter yyyy-mm-dd)` entry. - [ ] An [api updater] was added. - [ ] Deprecation of the API is explained in the CHANGELOG. - [ ] The users can understand why this API was removed and what they should use instead. --> Co-authored-by: Noel Stephens <noel.stephens@unity3d.com>
1 parent e0da299 commit 429b256

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,16 +1173,17 @@ internal void OnClientDisconnectFromServer(ulong clientId)
11731173
if (ownedObject)
11741174
{
11751175
// If destroying with owner, then always despawn and destroy (or defer destroying to prefab handler)
1176-
if (!ownedObject.DontDestroyWithOwner)
1176+
// Handle an object with no observers other than the current disconnecting client as destroying with owner
1177+
if (!ownedObject.DontDestroyWithOwner || ownedObject.Observers.Count == 0 || (ownedObject.Observers.Count == 1 && ownedObject.Observers.Contains(clientId)))
11771178
{
1178-
if (NetworkManager.PrefabHandler.ContainsHandler(clientOwnedObjects[i].GlobalObjectIdHash))
1179+
if (NetworkManager.PrefabHandler.ContainsHandler(ownedObject.GlobalObjectIdHash))
11791180
{
11801181
if (ownedObject.IsSpawned)
11811182
{
11821183
// Don't destroy (prefab handler will determine this, but always notify
11831184
NetworkManager.SpawnManager.DespawnObject(ownedObject, false, true);
11841185
}
1185-
NetworkManager.PrefabHandler.HandleNetworkPrefabDestroy(clientOwnedObjects[i]);
1186+
NetworkManager.PrefabHandler.HandleNetworkPrefabDestroy(ownedObject);
11861187
}
11871188
else
11881189
{
@@ -1240,6 +1241,12 @@ internal void OnClientDisconnectFromServer(ulong clientId)
12401241
{
12411242
continue;
12421243
}
1244+
1245+
// Skip destroy with owner objects as they will be processed by the outer loop
1246+
if (!childObject.DontDestroyWithOwner || childObject.Observers.Count == 0 || (childObject.Observers.Count == 1 && childObject.Observers.Contains(clientId)))
1247+
{
1248+
continue;
1249+
}
12431250
// If the client owner disconnected, it is ok to unlock this at this point in time.
12441251
if (childObject.IsOwnershipLocked)
12451252
{

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,8 +1975,8 @@ internal void DistributeNetworkObjects(ulong clientId)
19751975
// the owned distributable parent with the owned distributable children
19761976
foreach (var child in children)
19771977
{
1978-
// Ignore the parent and any child that does not have the same owner or that is already owned by the currently targeted client
1979-
if (child == ownerList.Value[i] || child.OwnerClientId != ownerList.Value[i].OwnerClientId || child.OwnerClientId == clientId)
1978+
// Ignore any child that does not have the same owner, that is already owned by the currently targeted client, or that doesn't have the targeted client as an observer
1979+
if (child == ownerList.Value[i] || child.OwnerClientId != ownerList.Value[i].OwnerClientId || child.OwnerClientId == clientId || !child.Observers.Contains(clientId))
19801980
{
19811981
continue;
19821982
}

0 commit comments

Comments
 (0)