Skip to content

Commit 4e35f84

Browse files
fix: In-scene placed NetworkObjects getting destroyed if early disconnect (up-port) (#2924)
* fix up-port of #2923 fix for in-scene placed NetworkObjects getting destroyed if a client disconnects early. * test adding test to validate fix * test fix Fixing issue of checking HasAuthority via NetworkObject as opposed to NetworkBehaviour
1 parent 0e10948 commit 4e35f84

File tree

4 files changed

+55
-7
lines changed

4 files changed

+55
-7
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1616

1717
### Fixed
1818

19+
- Fixed issue where in-scene placed NetworkObjects could be destroyed if a client disconnects early and/or before approval. (#2924)
1920
- Fixed issue where a `NetworkObject` component's associated `NetworkBehaviour` components would not be detected if scene loading is disabled in the editor and the currently loaded scene has in-scene placed `NetworkObject`s. (#2912)
2021
- Fixed issue where an in-scene placed `NetworkObject` with `NetworkTransform` that is also parented under a `GameObject` would not properly synchronize when the parent `GameObject` had a world space position other than 0,0,0. (#2898)
2122

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1245,7 +1245,7 @@ internal void DespawnAndDestroyNetworkObjects()
12451245
{
12461246
// If it is an in-scene placed NetworkObject then just despawn and let it be destroyed when the scene
12471247
// is unloaded. Otherwise, despawn and destroy it.
1248-
var shouldDestroy = !(networkObjects[i].IsSceneObject != null && networkObjects[i].IsSceneObject.Value);
1248+
var shouldDestroy = !(networkObjects[i].IsSceneObject == null || (networkObjects[i].IsSceneObject != null && networkObjects[i].IsSceneObject.Value));
12491249

12501250
// If we are going to destroy this NetworkObject, check for any in-scene placed children that need to be removed
12511251
if (shouldDestroy)

testproject/Assets/Tests/Manual/InSceneObjectParentingTests/InSceneParentChildHandler.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ private bool CheckForAuthority()
132132

133133
public void DeparentAllChildren(bool worldPositionStays = true)
134134
{
135-
if (IsRootParent && CheckForAuthority())
135+
if (IsRootParent && HasAuthority)
136136
{
137137
var lastChild = GetLastChild(transform);
138138
if (lastChild != null)
@@ -163,15 +163,15 @@ private void ParentChild(InSceneParentChildHandler child, bool worldPositionStay
163163

164164
public void ReParentAllChildren(bool worldPositionStays = true)
165165
{
166-
if (IsRootParent && CheckForAuthority())
166+
if (IsRootParent && HasAuthority)
167167
{
168168
ParentChild(m_Child, worldPositionStays);
169169
}
170170
}
171171

172172
public override void OnNetworkSpawn()
173173
{
174-
if (CheckForAuthority())
174+
if (HasAuthority)
175175
{
176176
LogMessage($"[{NetworkObjectId}] Pos = ({m_TargetLocalPosition}) | Rotation ({m_TargetLocalRotation}) | Scale ({m_TargetLocalScale})");
177177
if (AddNetworkTransform)
@@ -206,7 +206,7 @@ public override void OnNetworkSpawn()
206206

207207
public void DeparentSetValuesAndReparent()
208208
{
209-
if (IsRootParent && CheckForAuthority())
209+
if (IsRootParent && HasAuthority)
210210
{
211211
// Back to back de-parenting and re-parenting
212212
s_GenerateRandomValues = true;
@@ -222,7 +222,7 @@ public void DeparentSetValuesAndReparent()
222222
/// </summary>
223223
public override void OnNetworkObjectParentChanged(NetworkObject parentNetworkObject)
224224
{
225-
if (!CheckForAuthority() || !IsSpawned || parentNetworkObject != null || !s_GenerateRandomValues)
225+
if (!HasAuthority || !IsSpawned || parentNetworkObject != null || !s_GenerateRandomValues)
226226
{
227227
return;
228228
}
@@ -242,7 +242,7 @@ public override void OnNetworkObjectParentChanged(NetworkObject parentNetworkObj
242242

243243
private void LateUpdate()
244244
{
245-
if (!IsSpawned || !CheckForAuthority() || NetworkManagerTestDisabler.IsIntegrationTest)
245+
if (!IsSpawned || !HasAuthority || NetworkManagerTestDisabler.IsIntegrationTest)
246246
{
247247
return;
248248
}

testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,4 +578,51 @@ protected bool ScaleValuesMatch(Transform transformA, Transform transformB)
578578
}
579579

580580
}
581+
582+
internal class InScenePlacedNetworkObjectClientTests : NetcodeIntegrationTest
583+
{
584+
private const string k_SceneToLoad = "InSceneNetworkObject";
585+
586+
protected override int NumberOfClients => 0;
587+
588+
private Scene m_Scene;
589+
590+
protected override IEnumerator OnSetup()
591+
{
592+
SceneManager.sceneLoaded += SceneManager_sceneLoaded;
593+
SceneManager.LoadScene(k_SceneToLoad, LoadSceneMode.Additive);
594+
return base.OnSetup();
595+
}
596+
597+
private void SceneManager_sceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
598+
{
599+
if (scene.name == k_SceneToLoad && loadSceneMode == LoadSceneMode.Additive)
600+
{
601+
m_Scene = scene;
602+
SceneManager.sceneLoaded -= SceneManager_sceneLoaded;
603+
}
604+
}
605+
606+
protected override IEnumerator OnTearDown()
607+
{
608+
if (m_Scene.isLoaded)
609+
{
610+
SceneManager.UnloadSceneAsync(m_Scene);
611+
}
612+
return base.OnTearDown();
613+
}
614+
615+
[UnityTest]
616+
public IEnumerator DespawnAndDestroyNetworkObjects()
617+
{
618+
// Simulate a client disconnecting early by just invoking DespawnAndDestroyNetworkObjects to assure
619+
// this method does not destroy in-scene placed NetworkObjects.
620+
m_ServerNetworkManager.SpawnManager.DespawnAndDestroyNetworkObjects();
621+
622+
yield return s_DefaultWaitForTick;
623+
624+
var insceneObject = GameObject.Find("InSceneObject");
625+
Assert.IsNotNull(insceneObject, $"Could not find the in-scene placed {nameof(NetworkObject)}: InSceneObject!");
626+
}
627+
}
581628
}

0 commit comments

Comments
 (0)