Skip to content

Commit 2f5591f

Browse files
committed
fixes
1 parent 835e6bc commit 2f5591f

File tree

12 files changed

+69
-27
lines changed

12 files changed

+69
-27
lines changed

com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,13 +1280,7 @@ public SceneEventProgressStatus UnloadScene(Scene scene)
12801280
}
12811281
}
12821282

1283-
sceneEventProgress.LoadSceneMode = LoadSceneMode.Additive;
1284-
1285-
// Any NetworkObjects marked to not be destroyed with a scene and reside within the scene about to be unloaded
1286-
// should be migrated temporarily into the DDOL, once the scene is unloaded they will be migrated into the
1287-
// currently active scene.
12881283
var networkManager = NetworkManager;
1289-
SceneManagerHandler.MoveObjectsFromSceneToDontDestroyOnLoad(ref networkManager, scene);
12901284

12911285
var sceneEventData = BeginSceneEvent();
12921286
sceneEventData.SceneEventProgressId = sceneEventProgress.Guid;
@@ -1297,10 +1291,16 @@ public SceneEventProgressStatus UnloadScene(Scene scene)
12971291

12981292
// This will be the message we send to everyone when this scene event sceneEventProgress is complete
12991293
sceneEventProgress.SceneEventType = SceneEventType.UnloadEventCompleted;
1294+
sceneEventProgress.LoadSceneMode = LoadSceneMode.Additive;
13001295

13011296
sceneEventProgress.SceneEventId = sceneEventData.SceneEventId;
13021297
sceneEventProgress.OnSceneEventCompleted = OnSceneUnloaded;
13031298

1299+
// Any NetworkObjects marked to not be destroyed with a scene and reside within the scene about to be unloaded
1300+
// should be migrated temporarily into the DDOL, once the scene is unloaded they will be migrated into the
1301+
// currently active scene.
1302+
SceneManagerHandler.MoveObjectsFromSceneToDontDestroyOnLoad(ref networkManager, scene);
1303+
13041304
if (!RemoveServerClientSceneHandle(sceneEventData.SceneHandle, scene.handle))
13051305
{
13061306
Debug.LogError($"Failed to remove {SceneNameFromHash(sceneEventData.SceneHash)} scene handles [Server ({sceneEventData.SceneHandle})][Local({scene.handle})]");
@@ -2831,6 +2831,27 @@ internal bool IsSceneEventInProgress()
28312831
return false;
28322832
}
28332833

2834+
internal bool IsSceneUnloading(NetworkObject networkObject)
2835+
{
2836+
if (!NetworkManager.NetworkConfig.EnableSceneManagement)
2837+
{
2838+
return false;
2839+
}
2840+
2841+
foreach (var sceneEventEntry in SceneEventProgressTracking)
2842+
{
2843+
var name = SceneNameFromHash(sceneEventEntry.Value.SceneHash);
2844+
var scene = SceneManager.GetSceneByName(name);
2845+
var sameScene = name == networkObject.gameObject.scene.name && scene.handle == networkObject.SceneOriginHandle;
2846+
2847+
if (!sceneEventEntry.Value.HasTimedOut() && sceneEventEntry.Value.IsUnloading() && sceneEventEntry.Value.Status == SceneEventProgressStatus.Started && sameScene)
2848+
{
2849+
return true;
2850+
}
2851+
}
2852+
return false;
2853+
}
2854+
28342855
/// <summary>
28352856
/// Handles notifying clients when a NetworkObject has been migrated into a new scene
28362857
/// </summary>

com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventProgress.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,14 @@ internal void ClientFinishedSceneEvent(ulong clientId)
223223
}
224224
}
225225

226+
/// <summary>
227+
/// Returns whether the SceneEventType is related to an unloading event.
228+
/// </summary>
229+
internal bool IsUnloading()
230+
{
231+
return SceneEventType is SceneEventType.Unload or SceneEventType.UnloadComplete or SceneEventType.UnloadEventCompleted;
232+
}
233+
226234
/// <summary>
227235
/// Determines if the scene event has finished for both
228236
/// client(s) and server.

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,25 +1607,20 @@ internal void OnDespawnObject(NetworkObject networkObject, bool destroyGameObjec
16071607
// We have to do this check first as subsequent checks assume we can access NetworkObjectId.
16081608
if (!networkObject)
16091609
{
1610-
Debug.LogWarning("Trying to destroy network object but it is null");
1610+
NetworkLog.LogWarning("Trying to destroy network object but it is null");
16111611
return;
16121612
}
16131613

16141614
// Removal of spawned object
16151615
if (!SpawnedObjects.ContainsKey(networkObject.NetworkObjectId))
16161616
{
1617-
if (!NetworkManager.ShutdownInProgress)
1617+
if (!NetworkManager.ShutdownInProgress && !NetworkManager.SceneManager.IsSceneEventInProgress())
16181618
{
1619-
Debug.LogWarning($"Trying to destroy object {networkObject.NetworkObjectId} but it doesn't seem to exist anymore!");
1619+
NetworkLog.LogWarning($"Trying to destroy object {networkObject.NetworkObjectId} but it doesn't seem to exist anymore!");
16201620
}
16211621
return;
16221622
}
16231623

1624-
if (destroyGameObject && networkObject.IsSceneObject == true && NetworkLog.CurrentLogLevel <= LogLevel.Developer)
1625-
{
1626-
Debug.LogWarning("Destroying in-scene network objects can lead to unexpected behavior. It is recommended to use NetworkObject.Despawn(false) instead.");
1627-
}
1628-
16291624
var distributedAuthority = NetworkManager.DistributedAuthorityMode;
16301625
var hasDAAuthority = distributedAuthority && (networkObject.HasAuthority || (NetworkManager.DAHost && authorityOverride));
16311626
var hasClientServerAuthority = !distributedAuthority && NetworkManager.IsServer;
@@ -1635,6 +1630,11 @@ internal void OnDespawnObject(NetworkObject networkObject, bool destroyGameObjec
16351630
// and only attempt to remove the child's parent on the server-side
16361631
if (!NetworkManager.ShutdownInProgress && hasAuthority)
16371632
{
1633+
if (destroyGameObject && networkObject.IsSceneObject == true && !NetworkManager.SceneManager.IsSceneUnloading(networkObject))
1634+
{
1635+
NetworkLog.LogWarning("Destroying in-scene network objects can lead to unexpected behavior. It is recommended to use NetworkObject.Despawn(false) instead.");
1636+
}
1637+
16381638
// Get all child NetworkObjects
16391639
var objectsToRemoveParent = networkObject.GetComponentsInChildren<NetworkObject>();
16401640

testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObject.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectBase.cs renamed to testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObject/InSceneObjectBase.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@
66

77
namespace TestProject.RuntimeTests
88
{
9-
public class InScenePlacedNetworkObjectBase : IntegrationTestWithApproximation
9+
public class InSceneObjectBase : IntegrationTestWithApproximation
1010
{
1111
protected override int NumberOfClients => 2;
1212

1313
internal const string SceneToLoad = "InSceneNetworkObject";
1414
private Scene m_AuthoritySideSceneLoaded;
1515
private Scene m_PreviousSceneLoaded;
1616

17-
protected InScenePlacedNetworkObjectBase(NetworkTopologyTypes networkTopologyType, HostOrServer hostOrServer) : base(networkTopologyType, hostOrServer) { }
17+
protected InSceneObjectBase(NetworkTopologyTypes networkTopologyType, HostOrServer hostOrServer) : base(networkTopologyType, hostOrServer) { }
1818

1919
// Constructor that is used by InScenePlacedNetworkObjectDestroyTests
20-
protected InScenePlacedNetworkObjectBase(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { }
20+
protected InSceneObjectBase(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { }
2121

2222
protected override IEnumerator OnSetup()
2323
{
@@ -36,6 +36,7 @@ protected override IEnumerator OnSetup()
3636
protected override IEnumerator OnTearDown()
3737
{
3838
GetAuthorityNetworkManager().SceneManager.OnSceneEvent -= OnSceneEvent;
39+
NetworkObjectTestComponent.Reset();
3940
yield return CleanUpLoadedScene();
4041
}
4142

testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectDestroyTests.cs renamed to testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObject/InSceneObjectDestroyTests.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ namespace TestProject.RuntimeTests
1515
[TestFixture(NetworkTopologyTypes.DistributedAuthority, DespawnMode.Despawn)]
1616
[TestFixture(NetworkTopologyTypes.DistributedAuthority, DespawnMode.DeferDespawn)]
1717
[TestFixture(NetworkTopologyTypes.ClientServer, DespawnMode.Despawn)]
18-
public class InScenePlacedNetworkObjectDestroyTests : InScenePlacedNetworkObjectBase
18+
public class InSceneObjectDestroyTests : InSceneObjectBase
1919
{
2020
protected override int NumberOfClients => 2;
2121

2222
private readonly DespawnMode m_DespawnMode;
2323

24-
public InScenePlacedNetworkObjectDestroyTests(NetworkTopologyTypes networkTopologyType, DespawnMode despawnMode) : base(networkTopologyType)
24+
public InSceneObjectDestroyTests(NetworkTopologyTypes networkTopologyType, DespawnMode despawnMode) : base(networkTopologyType)
2525
{
2626
m_DespawnMode = despawnMode;
2727
}
@@ -95,6 +95,16 @@ private IEnumerator LoadSceneAndDespawnObject(DestroyMode destroyMode)
9595
serverObject.DeferDespawn(1, destroyGameObject);
9696
}
9797

98+
const string expectedLog = "[Netcode] Destroying in-scene network objects can lead to unexpected behavior. It is recommended to use NetworkObject.Despawn(false) instead.";
99+
if (destroyGameObject)
100+
{
101+
NetcodeLogAssert.LogWasReceived(LogType.Warning, expectedLog);
102+
}
103+
else
104+
{
105+
NetcodeLogAssert.LogWasNotReceived(LogType.Warning, expectedLog);
106+
}
107+
98108
yield return WaitForConditionOrTimeOut(() => NetworkObjectTestComponent.SpawnedInstances.Count == 0);
99109
AssertOnTimeout($"Timed out waiting for all in-scene instances to be despawned! Current spawned count: {NetworkObjectTestComponent.SpawnedInstances.Count()}");
100110

testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectDestroyTests.cs.meta renamed to testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObject/InSceneObjectDestroyTests.cs.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObjectParentingTests.cs renamed to testproject/Assets/Tests/Runtime/NetworkSceneManager/InScenePlacedNetworkObject/InSceneObjectParentingTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ namespace TestProject.RuntimeTests
1212
[TestFixture(NetworkTopologyTypes.DistributedAuthority, HostOrServer.DAHost)]
1313
[TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.Host)]
1414
[TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.Server)]
15-
public class InScenePlacedNetworkObjectParentingTests : InScenePlacedNetworkObjectBase
15+
public class InSceneObjectParentingTests : InSceneObjectBase
1616
{
1717
protected override int NumberOfClients => 2;
1818

1919
private const string k_InSceneUnder = "InSceneUnderGameObject";
2020
private const string k_InSceneUnderWithNetworkTransform = "InSceneUnderGameObjectWithNT";
2121

22-
public InScenePlacedNetworkObjectParentingTests(NetworkTopologyTypes networkTopologyType, HostOrServer hostOrServer) : base(networkTopologyType, hostOrServer) { }
22+
public InSceneObjectParentingTests(NetworkTopologyTypes networkTopologyType, HostOrServer hostOrServer) : base(networkTopologyType, hostOrServer) { }
2323

2424
[UnityTest]
2525
public IEnumerator ParentedInSceneObjectLateJoiningClient()

0 commit comments

Comments
 (0)