From 97ebd033c2af688d6dcdfb8112e3bd16bae3c2d0 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Tue, 7 Sep 2021 13:26:11 -0500 Subject: [PATCH 1/3] fix This allows for parented NetworkObjects to properly transition between scenes as well as disables the NetworkObjects during a scene transition (i.e. loading a scene in single mode) until the scene has been loaded right before the NetworkObjects are moved back into the newly loaded currently active scene. --- .../SceneManagement/NetworkSceneManager.cs | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs index 00bed26a3c..9cb6dc4f0f 100644 --- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs @@ -1580,15 +1580,24 @@ private void MoveObjectsToDontDestroyOnLoad() foreach (var sobj in objectsToKeep) { - //In case an object has been set as a child of another object it has to be removed from the parent in order to be moved from one scene to another. + // In case an object has been set as a child of another object, if the parent is a NetworkObject then we don't + // need to move this into the DontDestroyOnLoad scene because when the parent is moved it will automatically + // move its children into the DontDestroyOnLoad scene. if (sobj.gameObject.transform.parent != null) { - sobj.gameObject.transform.parent = null; + if (sobj.gameObject.GetComponentInParent() != null) + { + // Since we are doing a scene transition, disable the GameObject until the next scene is loaded + sobj.gameObject.SetActive(false); + continue; + } } if (!sobj.DestroyWithScene || (sobj.IsSceneObject != null && sobj.IsSceneObject.Value && sobj.gameObject.scene == DontDestroyOnLoadScene)) { UnityEngine.Object.DontDestroyOnLoad(sobj.gameObject); + // Since we are doing a scene transition, disable the GameObject until the next scene is loaded + sobj.gameObject.SetActive(false); } else if (m_NetworkManager.IsServer) { @@ -1657,17 +1666,25 @@ private void MoveObjectsToScene(Scene scene) foreach (var sobj in objectsToKeep) { - //In case an object has been set as a child of another object it has to be removed from the parent in order to be moved from one scene to another. + // In case an object has been set as a child of another object, if the parent is a NetworkObject then we don't + // need to move this into the scene because when the parent is moved it will automatically move its children + // into the scene. if (sobj.gameObject.transform.parent != null) { - sobj.gameObject.transform.parent = null; + if (sobj.gameObject.GetComponentInParent() != null) + { + // We set the child NetworkObject to active at this point + sobj.gameObject.SetActive(true); + continue; + } } if (sobj.gameObject.scene == DontDestroyOnLoadScene && (sobj.IsSceneObject == null || sobj.IsSceneObject.Value)) { continue; } - + // We set the NetworkObject to active at this point + sobj.gameObject.SetActive(true); SceneManager.MoveGameObjectToScene(sobj.gameObject, scene); } } From 41ede04d3d9b54e4bd41a779a06dac95401d421a Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Tue, 7 Sep 2021 16:36:41 -0500 Subject: [PATCH 2/3] refactor After consulting and verifying fix with Fatih, there was some refactoring to assure only non-parented GameObject transforms were migrated as all children would follow. Additionally changed the name from MoveObjectsToScene to MoveObjectsFromDontDestroyOnLoadToScene for better clarity of what the method did. --- .../SceneManagement/NetworkSceneManager.cs | 43 ++++++------------- 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs index 9cb6dc4f0f..c7b2b8ddcc 100644 --- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs @@ -994,7 +994,7 @@ private void OnSceneLoaded(string sceneName) if (SceneEventData.LoadSceneMode == LoadSceneMode.Single) { // Move all objects to the new scene - MoveObjectsToScene(nextScene); + MoveObjectsFromDontDestroyOnLoadToScene(nextScene); } // The Condition: While a scene is asynchronously loaded in single loading scene mode, if any new NetworkObjects are spawned @@ -1580,25 +1580,16 @@ private void MoveObjectsToDontDestroyOnLoad() foreach (var sobj in objectsToKeep) { - // In case an object has been set as a child of another object, if the parent is a NetworkObject then we don't - // need to move this into the DontDestroyOnLoad scene because when the parent is moved it will automatically - // move its children into the DontDestroyOnLoad scene. - if (sobj.gameObject.transform.parent != null) + if (!sobj.DestroyWithScene || (sobj.IsSceneObject != null && sobj.IsSceneObject.Value && sobj.gameObject.scene == DontDestroyOnLoadScene)) { - if (sobj.gameObject.GetComponentInParent() != null) + // Only move objects with no parent as child objects will follow + if (sobj.gameObject.transform.parent == null) { + UnityEngine.Object.DontDestroyOnLoad(sobj.gameObject); // Since we are doing a scene transition, disable the GameObject until the next scene is loaded sobj.gameObject.SetActive(false); - continue; } } - - if (!sobj.DestroyWithScene || (sobj.IsSceneObject != null && sobj.IsSceneObject.Value && sobj.gameObject.scene == DontDestroyOnLoadScene)) - { - UnityEngine.Object.DontDestroyOnLoad(sobj.gameObject); - // Since we are doing a scene transition, disable the GameObject until the next scene is loaded - sobj.gameObject.SetActive(false); - } else if (m_NetworkManager.IsServer) { sobj.Despawn(true); @@ -1659,33 +1650,25 @@ private void PopulateScenePlacedObjects(Scene sceneToFilterBy, bool clearScenePl /// Moves all spawned NetworkObjects (from do not destroy on load) to the scene specified /// /// scene to move the NetworkObjects to - private void MoveObjectsToScene(Scene scene) + private void MoveObjectsFromDontDestroyOnLoadToScene(Scene scene) { // Move ALL NetworkObjects to the temp scene var objectsToKeep = m_NetworkManager.SpawnManager.SpawnedObjectsList; foreach (var sobj in objectsToKeep) { - // In case an object has been set as a child of another object, if the parent is a NetworkObject then we don't - // need to move this into the scene because when the parent is moved it will automatically move its children - // into the scene. - if (sobj.gameObject.transform.parent != null) + if (sobj.gameObject.scene == DontDestroyOnLoadScene && (sobj.IsSceneObject == null || sobj.IsSceneObject.Value)) { - if (sobj.gameObject.GetComponentInParent() != null) - { - // We set the child NetworkObject to active at this point - sobj.gameObject.SetActive(true); - continue; - } + continue; } - if (sobj.gameObject.scene == DontDestroyOnLoadScene && (sobj.IsSceneObject == null || sobj.IsSceneObject.Value)) + // Only move objects with no parent as child objects will follow + if (sobj.gameObject.transform.parent == null) { - continue; + // We set the child NetworkObject to active at this point + sobj.gameObject.SetActive(true); + SceneManager.MoveGameObjectToScene(sobj.gameObject, scene); } - // We set the NetworkObject to active at this point - sobj.gameObject.SetActive(true); - SceneManager.MoveGameObjectToScene(sobj.gameObject, scene); } } } From 0336aa6fc3e17e66d50f77a2b7f6ab876363db04 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Tue, 7 Sep 2021 16:47:23 -0500 Subject: [PATCH 3/3] style fixing the clarity of one comment. --- .../Runtime/SceneManagement/NetworkSceneManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs index c7b2b8ddcc..60e5e9191c 100644 --- a/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs @@ -1665,7 +1665,7 @@ private void MoveObjectsFromDontDestroyOnLoadToScene(Scene scene) // Only move objects with no parent as child objects will follow if (sobj.gameObject.transform.parent == null) { - // We set the child NetworkObject to active at this point + // set it back to active at this point sobj.gameObject.SetActive(true); SceneManager.MoveGameObjectToScene(sobj.gameObject, scene); }