Skip to content

Commit 65c4dc8

Browse files
refactor
Refactoring my approach.
1 parent 1d6a440 commit 65c4dc8

File tree

3 files changed

+20
-51
lines changed

3 files changed

+20
-51
lines changed

com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,7 @@ public void SetSceneObjectStatus(bool isSceneObject = false)
11941194
/// Gets whether or not the object should be automatically removed when the scene is unloaded.
11951195
/// </summary>
11961196
public bool DestroyWithScene { get; set; }
1197+
internal bool DestroyPendingSceneEvent;
11971198

11981199
/// <summary>
11991200
/// When set to true and the active scene is changed, this will automatically migrate the <see cref="NetworkObject"/>
@@ -1714,18 +1715,11 @@ private void OnDestroy()
17141715
return;
17151716
}
17161717

1717-
// Authority is the server (client-server) and the owner or DAHost (distributed authority) when destroying a NetworkObject
1718-
var isAuthority = HasAuthority || NetworkManager.DAHost;
1718+
// An authoritzed destroy is when it is happening on the authority instance or it is being destroyed due to
1719+
// a scene event that will automatically destroy any NetworkObject instances that should be destroyed with the scene.
1720+
var isAuthorityDestroy = HasAuthority || NetworkManager.DAHost || DestroyPendingSceneEvent;
17191721

1720-
// If we are not the authority, check to see if this is one of the edge case scenarios where a NetworkObject could be getting
1721-
// destroyed due to unloading a scene or loading a scene in single mode.
1722-
if (!isAuthority && IsSpawned && NetworkManager.DistributedAuthorityMode && NetworkManager.NetworkConfig.EnableSceneManagement
1723-
&& NetworkManager.SceneManager.ShouldObjectBeDestroyedWhenUnloaded(this))
1724-
{
1725-
isAuthority = true;
1726-
}
1727-
1728-
if (NetworkManager.IsListening && !isAuthority && IsSpawned &&
1722+
if (NetworkManager.IsListening && !isAuthorityDestroy && IsSpawned &&
17291723
(IsSceneObject == null || (IsSceneObject.Value != true)))
17301724
{
17311725
// If we destroyed a GameObject with a NetworkObject component on the non-authority side, handle cleaning up the SceneMigrationSynchronization.
@@ -1735,7 +1729,6 @@ private void OnDestroy()
17351729
// if this happens. Instead, we should just generate a network log error and exit early (as long as we are not shutting down).
17361730
if (!NetworkManager.ShutdownInProgress)
17371731
{
1738-
17391732
// Since we still have a session connection, log locally and on the server to inform user of this issue.
17401733
if (NetworkManager.LogLevel <= LogLevel.Error)
17411734
{

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,20 @@ public void MoveObjectsFromSceneToDontDestroyOnLoad(ref NetworkManager networkMa
293293
// Create a local copy of the spawned objects list since the spawn manager will adjust the list as objects
294294
// are despawned.
295295
var localSpawnedObjectsHashSet = new HashSet<NetworkObject>(networkManager.SpawnManager.SpawnedObjectsList);
296+
var distributedAuthority = networkManager.DistributedAuthorityMode;
296297
foreach (var networkObject in localSpawnedObjectsHashSet)
297298
{
298299
if (networkObject == null || (networkObject != null && networkObject.gameObject.scene.handle != scene.handle))
299300
{
300301
continue;
301302
}
302303

304+
// Check to determine if we need to allow destroying a non-authority instance
305+
if (distributedAuthority && networkObject.DestroyWithScene && !networkObject.HasAuthority)
306+
{
307+
networkObject.DestroyPendingSceneEvent = true;
308+
}
309+
303310
// Only NetworkObjects marked to not be destroyed with the scene and are not already in the DDOL are preserved
304311
if (!networkObject.DestroyWithScene && networkObject.gameObject.scene != networkManager.SceneManager.DontDestroyOnLoadScene)
305312
{
@@ -309,7 +316,7 @@ public void MoveObjectsFromSceneToDontDestroyOnLoad(ref NetworkManager networkMa
309316
UnityEngine.Object.DontDestroyOnLoad(networkObject.gameObject);
310317
}
311318
}
312-
else if (networkManager.IsServer)
319+
else if (networkObject.HasAuthority)
313320
{
314321
networkObject.Despawn();
315322
}

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

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2679,13 +2679,20 @@ internal void MoveObjectsToDontDestroyOnLoad()
26792679
// Create a local copy of the spawned objects list since the spawn manager will adjust the list as objects
26802680
// are despawned.
26812681
var localSpawnedObjectsHashSet = new HashSet<NetworkObject>(NetworkManager.SpawnManager.SpawnedObjectsList);
2682+
var distributedAuthority = NetworkManager.DistributedAuthorityMode;
26822683
foreach (var networkObject in localSpawnedObjectsHashSet)
26832684
{
26842685
if (networkObject == null || (networkObject != null && networkObject.gameObject.scene == DontDestroyOnLoadScene))
26852686
{
26862687
continue;
26872688
}
26882689

2690+
// Check to determine if we need to allow destroying a non-authority instance
2691+
if (distributedAuthority && networkObject.DestroyWithScene && !networkObject.HasAuthority)
2692+
{
2693+
networkObject.DestroyPendingSceneEvent = true;
2694+
}
2695+
26892696
// Only NetworkObjects marked to not be destroyed with the scene
26902697
if (!networkObject.DestroyWithScene)
26912698
{
@@ -2823,44 +2830,6 @@ internal bool IsSceneEventInProgress()
28232830
return false;
28242831
}
28252832

2826-
/// <summary>
2827-
/// Used to determine if it is valid for a distributed authority client to destroy a spawned object
2828-
/// based on any current scene event in progress and/or the GameObject's scene status.
2829-
/// <see cref="NetworkObject.OnDestroy"/>
2830-
/// </summary>
2831-
/// <param name="networkObject">the NetworkObject to check</param>
2832-
internal bool ShouldObjectBeDestroyedWhenUnloaded(NetworkObject networkObject)
2833-
{
2834-
if (!IsSceneEventInProgress())
2835-
{
2836-
return false;
2837-
}
2838-
if (!networkObject.gameObject.scene.isLoaded)
2839-
{
2840-
return networkObject.DestroyWithScene;
2841-
}
2842-
var objectScene = networkObject.gameObject.scene;
2843-
var objectSceneHash = SceneHashFromNameOrPath(objectScene.name);
2844-
foreach (var sceneEventEntry in SceneEventProgressTracking)
2845-
{
2846-
if (sceneEventEntry.Value.HasTimedOut())
2847-
{
2848-
continue;
2849-
}
2850-
if (sceneEventEntry.Value.SceneEventType == SceneEventType.Unload && sceneEventEntry.Value.Status == SceneEventProgressStatus.Started
2851-
&& sceneEventEntry.Value.SceneHash == objectSceneHash)
2852-
{
2853-
return networkObject.DestroyWithScene;
2854-
}
2855-
if (sceneEventEntry.Value.SceneEventType == SceneEventType.Load && sceneEventEntry.Value.LoadSceneMode == LoadSceneMode.Single &&
2856-
sceneEventEntry.Value.SceneHash != objectSceneHash)
2857-
{
2858-
return networkObject.DestroyWithScene;
2859-
}
2860-
}
2861-
return false;
2862-
}
2863-
28642833
/// <summary>
28652834
/// Handles notifying clients when a NetworkObject has been migrated into a new scene
28662835
/// </summary>

0 commit comments

Comments
 (0)