Repository navigation
Infinite hang when reloading a scene contains a manually spawned NetworkObject with a SpriteLibrary and a SpriteResolver #4095
Description
Activity
- addedtype:bugBug ReportBug Reportstat:awaiting-triageStatus - Awaiting triage from the Netcode team.Status - Awaiting triage from the Netcode team.stat:reply-neededAwaiting reply from Unity accountAwaiting reply from Unity account
on Jul 23, 2026 Actually it seems like SpriteLibrary/SpriteResolver are not needed for the bug to happen, simply replacing the sprite triggers the bug:
var go = NetworkManager.Singleton.SpawnManager.InstantiateAndSpawn( prefab!.GetComponent<NetworkObject>(), OwnerClientId, destroyWithScene: true, position: Vector3.zero ); go.GetComponent<SpriteRenderer>.sprite = [other sprite]Hi @acavailhez,
Recent post above:
Is this a typo?
go.GetComponent<SpriteRenderer>.sprite = [other sprite]It should be this:
go.GetComponent<SpriteRenderer>().sprite = [other sprite]Issue posted:
Issue-1: Destroy with scene on a spawned instance just prior to performing a LoadSceneMode.Single scene loading event
It looks like you are spawning a prefab instance in the currently active scene (where everything will be instantiated) and then immediately doing a scene loading event using
LoadSceneMode.Singlewhich will destroy anything in the currently active scene upon finishing the scene loading event (i.e. your spawned object is getting destroyed).Issue-2: For integrated scene management, use the
NetworkSceneManagercompleted events orOnSceneEventThe supported way to know a netcode synchronized scene event is finished is to use the
NetworkSceneManagerevents and not theUnityEngine.SceneManagement.SceneManagerdrivenTime.timeSinceLevelLoadas that can lead to scenarios whereUnityEngine.SceneManagement.SceneManageris finished butNetworkSceneManageris not.Issue-3: Using a
NetworkBehaviourto start theNetworkManagerWe do not recommend using a
NetworkBehaviourto start theNetworkManagerand while it might work under certain conditions, it coudl also lead to unexpected results/issues. The recommend component to use for startingNetworkManageris to use aMonoBehaviourand I personally would recommend using the pattern of placing that on the sameGameObjectas theNetworkManager.Resolution fix
Here is a quick modification of your script which should work.
using Unity.Multiplayer.PlayMode; using Unity.Netcode; using Unity.Netcode.Transports.UTP; using UnityEngine; using UnityEngine.SceneManagement; /// <summary> /// Add to your NetworkManager. /// </summary> /// <remarks> /// Don't use a NetworkBehaviour to start NetworkManager as NetworkBehaviours /// depend upon NetworkManager. /// </remarks> public class TestCrash : MonoBehaviour { public bool DestroyInstanceWithScene = false; [SerializeField] public GameObject PrefabToSpawn = null!; private NetworkManager m_NetworkManager; /// <summary> /// Requires: Multiplayer Playmode Tool /// Will start a host or client based on the editor window instance type. /// </summary> /// <returns>true or false as to whether the NetworkManager started.</returns> private bool QuickStart() { var unityTransport = m_NetworkManager.GetComponent<UnityTransport>(); // This should be pre-configured but ok to do this as well. unityTransport.UseWebSockets = false; // if applicable unityTransport.SetConnectionData("0.0.0.0", 7777); m_NetworkManager.NetworkConfig.NetworkTransport = unityTransport; // Main editor view always starts as host if (CurrentPlayer.IsMainEditor) { return m_NetworkManager.StartHost(); } else // MPPM virtual clients start as a client { return m_NetworkManager.StartClient(); } } private void Start() { m_NetworkManager = GetComponent<NetworkManager>(); if (m_NetworkManager == null) { Debug.LogError($"No {nameof(NetworkManager)} found! Add this component to the same {nameof(GameObject)} as your {nameof(NetworkManager)}!"); return; } if (!QuickStart()) { Debug.Log($"Failed to start {nameof(NetworkManager)} on {gameObject.name}!"); return; } // If not destroying with the scene, then it is ok to spawn in the current scene prior to a scene loading // event of type LoadSceneMode.Single (i.e. everything in the current active scene will be destroyed that // is marked to be destroyed). if (!DestroyInstanceWithScene) { // Ok to spawn an instance that doesn't destroy with a scene. SpawnPrefabInstance(); } // Use the completed scene events to know everyone has finished loading and synchronizing the scene. m_NetworkManager.SceneManager.OnLoadEventCompleted += OnLoadEventCompleted; m_NetworkManager.SceneManager.LoadScene(SceneManager.GetActiveScene().name, LoadSceneMode.Single); } private void SpawnPrefabInstance() { if (PrefabToSpawn == null) { Debug.Log($"Will not spawn prefab instance as it is not set!"); return; } NetworkObject.InstantiateAndSpawn(PrefabToSpawn, m_NetworkManager, destroyWithScene: DestroyInstanceWithScene, position: Vector3.zero); } private void OnLoadEventCompleted(string sceneName, LoadSceneMode loadSceneMode, System.Collections.Generic.List<ulong> clientsCompleted, System.Collections.Generic.List<ulong> clientsTimedOut) { Debug.Log($"[{sceneName}] Loaded via {loadSceneMode} scene mode."); // If you are destroying with the scene and immediately loading a scene using LoadSceneMode.Single, // then you need to spawn after the scene load to avoid having the newly spawned instance getting destroyed. if (DestroyInstanceWithScene) { SpawnPrefabInstance(); } } }
Let me know if this resolves your issues?
- addedstat:awaiting-responseAwaiting response from author. This label should be added manually.Awaiting response from author. This label should be added manually.and removedstat:reply-neededAwaiting reply from Unity accountAwaiting reply from Unity account
on Jul 23, 2026 - addedtype:supportQuestions or other supportQuestions or other supportand removedtype:bugBug ReportBug Reportstat:awaiting-triageStatus - Awaiting triage from the Netcode team.Status - Awaiting triage from the Netcode team.
on Jul 23, 2026 Hello @NoelStephensUnity!
About Issue 1
TestCrashwaits 3 seconds to reload the scene (it's not immediate)About Issue 2
I don't think the issue is related to scene lifecycle, I changed
TestCrashto wait 1 second before spawning the object and the bug still occursAbout Issue 3
When
TestCrashis aMonoBehaviorthe issue still occursHere's a simpler
TestCrashto reproduce the issue:public class TestCrash : MonoBehaviour { [SerializeField] public GameObject prefab = null!; [SerializeField] public Sprite spriteToSwap = null!; private bool _alreadReloaded; private bool _alreadySpawned; private void Start() { StartHost(); } private void Update() { SpawnInstanceAndSwapSpriteAfterOneSecond(); ReloadSceneAfterThreeSeconds(); } private void StartHost() { var networkManager = NetworkManager.Singleton; if (networkManager.IsListening) return; var unityTransport = networkManager.GetComponent<UnityTransport>(); unityTransport.UseWebSockets = false; unityTransport.SetConnectionData("0.0.0.0", 7777); networkManager!.NetworkConfig.NetworkTransport = unityTransport; networkManager.StartHost(); Debug.Log("Started host"); } private void SpawnInstanceAndSwapSpriteAfterOneSecond() { // Wait 1 second and spawn if (Time.timeSinceLevelLoad < 1f) return; if (_alreadySpawned) return; _alreadySpawned = true; var spawned = NetworkManager.Singleton.SpawnManager.InstantiateAndSpawn( prefab!.GetComponent<NetworkObject>(), destroyWithScene: true ); spawned.GetComponent<SpriteRenderer>().sprite = spriteToSwap; Debug.Log("Spawned object"); } private void ReloadSceneAfterThreeSeconds() { // Wait 3 seconds then reload the current scene if (Time.timeSinceLevelLoad < 3f) return; if (_alreadReloaded) return; _alreadReloaded = true; Debug.Log("Reload scene"); NetworkManager.Singleton.SceneManager.LoadScene(SceneManager.GetActiveScene().name, LoadSceneMode.Single); } }The first reload works, but the second reload hangs forever
- addedstat:reply-neededAwaiting reply from Unity accountAwaiting reply from Unity accountand removedstat:awaiting-responseAwaiting response from author. This label should be added manually.Awaiting response from author. This label should be added manually.
on Jul 23, 2026 Here is an exported package that you can import into your project and it does exactly what you are trying to do but does not lock or crash the editor.
Issue4095.zip
Once imported, add the TestScene to your scenes in build list, open it, and enter play mode.
The provided contents of the exported package continually reloads the scene every 3 second (what I had set as the default), changes the sprite on a newly spawned object, and will not cause any race conditions/crashes to occur.This line:
NetworkManager.Singleton.SceneManager.LoadScene(SceneManager.GetActiveScene().name, LoadSceneMode.Single);Coupled with how you are checking if the scene is loaded is where you are running into issues.
This code (based on my first response):
if (Time.timeSinceLevelLoad < 1f) return;Is not a Netcode for GameObjects supported way to determine if a scene loading event has completed or not. This is actually a portion of the reason why you are having issues with your approach. I am just trying to point out that you are using a technique that we don't support so if you run into issues using this approach there is not much we can do to help you resolve that issue.
The other issue is that you are reloading the same scene that has your NetworkManager within it...thus you are creating a new instance that is automatically migrated into the DDOL each time you reload the same scene.
Here is a modified version of your project that has all sorts of catches in it where you could run into issues.
The first issue it will run into is that you are creating more than one NetworkManager instance.
It stops after the 1st scene load because it destroys the 2nd NetworkManager.
If you were to adjust your code to assure that the 1st instance (pre-loaded scene) will create a Coroutine to reload the scene after (n) seconds (as is done in the script provided in the above exported package) then it will start working more as expected...but you still need to destroy that additional NetworkManager.using Unity.Netcode; using Unity.Netcode.Transports.UTP; using UnityEngine; using UnityEngine.SceneManagement; public class TestCrashWithChecks : MonoBehaviour { private static bool AbortTest; [SerializeField] public GameObject prefab = null!; [SerializeField] public Sprite spriteToSwap = null!; private bool _alreadReloaded; private bool _alreadySpawned; private bool m_DoNotUpdate; private void Start() { m_LoadCounter++; if (AbortTest) { Debug.Log("Not starting host again as the test was aborted!"); } var networkManager = GetComponent<NetworkManager>(); if (NetworkManager.Singleton != null && NetworkManager.Singleton.IsConnectedClient && networkManager != NetworkManager.Singleton) { Debug.LogError("Multiple NetworkManagers detected! Destroying this new instance!"); Destroy(gameObject); m_DoNotUpdate = true; return; } StartHost(); } private void Update() { if (AbortTest || m_DoNotUpdate) { return; } SpawnInstanceAndSwapSpriteAfterOneSecond(); ReloadSceneAfterThreeSeconds(); } private void StartHost() { if (NetworkManager.Singleton != null && NetworkManager.Singleton.IsConnectedClient) { return; } var networkManager = NetworkManager.Singleton; var unityTransport = networkManager.GetComponent<UnityTransport>(); unityTransport.UseWebSockets = false; unityTransport.SetConnectionData("0.0.0.0", 7777); networkManager!.NetworkConfig.NetworkTransport = unityTransport; if (networkManager.StartHost()) { Debug.Log("Started host"); } else { Debug.Log("Failed to start host"); AbortTest = true; } } private void SpawnInstanceAndSwapSpriteAfterOneSecond() { // Wait 1 second and spawn if (Time.timeSinceLevelLoad < 1f) return; if (_alreadySpawned) return; try { _alreadySpawned = true; var spawned = NetworkManager.Singleton.SpawnManager.InstantiateAndSpawn( prefab!.GetComponent<NetworkObject>(), destroyWithScene: false ); if (spawned != null) { spawned.GetComponent<SpriteRenderer>().sprite = spriteToSwap; Debug.Log("Spawned object"); } else { Debug.Log("Failed to spawn object!"); AbortTest = true; } } catch(System.Exception ex) { AbortTest = true; Debug.LogException(ex); } } private string m_SceneNameToLoad; private static int m_LoadCounter; private void ReloadSceneAfterThreeSeconds() { // Wait 3 seconds then reload the current scene if (Time.timeSinceLevelLoad < 3f) return; if (_alreadReloaded) return; if (m_LoadCounter > 1 && (!LastSceneLoadCompleted || m_DoNotUpdate) ) { Debug.LogError("This would have tried to load a scene before it was finished!"); return; } _alreadReloaded = true; LastSceneLoadCompleted = false; Debug.Log("Reload scene"); NetworkManager.Singleton.SceneManager.OnLoadEventCompleted += SceneManager_OnLoadEventCompleted; m_SceneNameToLoad = SceneManager.GetActiveScene().name; var sceneLoadStatus = NetworkManager.Singleton.SceneManager.LoadScene(SceneManager.GetActiveScene().name, LoadSceneMode.Single); if (sceneLoadStatus != SceneEventProgressStatus.Started) { AbortTest = true; Debug.LogError($"Scene loading failed because: {sceneLoadStatus}"); } } static bool LastSceneLoadCompleted; private void SceneManager_OnLoadEventCompleted(string sceneName, LoadSceneMode loadSceneMode, System.Collections.Generic.List<ulong> clientsCompleted, System.Collections.Generic.List<ulong> clientsTimedOut) { if (m_SceneNameToLoad == sceneName) { NetworkManager.Singleton.SceneManager.OnLoadEventCompleted -= SceneManager_OnLoadEventCompleted; LastSceneLoadCompleted = true; } } }
You want to use m_NetworkManager.SceneManager.OnLoadEventCompleted to signal that everyone has loaded and processed everything within the newly loaded scene. We support that approach and if you run into issues using that approach we can help you resolve your issue or if it is a bug we can fix it.
If you want to use this pattern (i.e. just reload the same currently loaded active scene over and over), then you would most likely want to use a "BootStrap" scene approach where: (I did not make these adjustments to your script)
- The boot strap scene is your first scene loaded.
- This contains your NetworkManager and other global/non-spawned managers attached to the same GameObject so they all end up in the DDOL and persist.
- The TestCrash class would then use something like a Coroutine that reloads the same target scene after (n) seconds.
- But not the boot strap scene...you would want a 2nd scene that you reload over and over.
- The target scene to load should not contain NetworkManager or the thing that is continually reloading the same scene.
(The example in the package I provided does not do this but does show that you can accomplish what you are trying to do if you use the supported way to handle detecting when a scene loading event has completed.)
Here are some links to our documentation that you might find useful
Don't use NetworkBehaviour to start NetworkManager
Notifications for instantiating and destroying NetworkManager
Let me know if this helps you resolve your issue?
- The boot strap scene is your first scene loaded.
- addedstat:awaiting-responseAwaiting response from author. This label should be added manually.Awaiting response from author. This label should be added manually.
on Jul 23, 2026 8 remaining items
- addedstat:reply-neededAwaiting reply from Unity accountAwaiting reply from Unity accountand removedstat:awaiting-responseAwaiting response from author. This label should be added manually.Awaiting response from author. This label should be added manually.
on Aug 11, 2026 Ah, I think I understand. Just to clarify, your core issue is that the Unity Editor is hanging, not that your Netcode logic isn't working? You're right that it's not expected that the Unity editor hangs forever in this case. We've not been able to reproduce the engine hang on our end.
This github repo is for specifically Netcode for GameObjects issues. Seeing as this editor hang crosses a few product boundaries it's going to be easiest for us to address if you can report a bug in the editor. Feel free to link your case number here and we can follow up on your report to ensure it gets to the right place.
Reacted by Noel Stephens- addedstat:awaiting-responseAwaiting response from author. This label should be added manually.Awaiting response from author. This label should be added manually.and removedstat:reply-neededAwaiting reply from Unity accountAwaiting reply from Unity account
on Aug 11, 2026 @acavailhez
I did replicate the issue and tried several combinations to resolve the issue. (Using 6000.4.0f1)
It does appear (oddly enough) that only if you replace the sprite and mark the instance to not destroy with the scene load (single mode) then (on my side using Windows 11) it ends up freezing the editor (attaching with a debugger isn't very useful either under this scenario as well).However, if I comment out the code that swaps the sprite, then it runs perfectly fine. (🔥)
As @EmandM mentioned, this does seem like an editor specific issue that you can file as an editor related bug report via the editor.
However, we understand the pain associated with not being able to achieve something that does seem simple but ends up being an edge case issue. When using
LoadSceneMode.Single, it places a lot of the control over to the SceneManager for things like when a scene is fully unloaded (and the assets within the scene) which could potentially expose a bug under very specific timing related circumstances.Typically, I recommend using an additive scene loading flow. This provides you with a bit more control over when you want to unload or load a scene and you can change the timing for both based on your project's needs.
As such, here is an example project that accomplishes the same thing you were trying to do using
LoadSeneMode.Singlebut it uses the additive scene loading pattern:Below is a video of the project running and shows you can switch the mode (destroy with scene or don't destroy with scene) on the fly in playmode and it continues to work whether destroying or not destroying when the scene it is currently within is unloaded (and it replaces the sprite on the newly instantiated and spawned instance):
GH-4095-Solution.mov
Let me know if this approach works for you (at least until the current issue when using SingleMode scene loading is resolved)?
Hi @NoelStephensUnity !
Thanks a lot for your time and effort!
I think additive scene loading is not going to work for what I'm doing, but I appreciate the idea.
The lock contention only happens in the editor so I have a workaround for now. I'd to remove it one day!
- addedstat:reply-neededAwaiting reply from Unity accountAwaiting reply from Unity accountand removedstat:awaiting-responseAwaiting response from author. This label should be added manually.Awaiting response from author. This label should be added manually.
on Aug 18, 2026 @acavailhez
This has been identified as an engine issue and should be resolved (currently) in the following editor versions:
6000.3.24f1, 6000.5.3f1 and 6000.6.No 6000.4 released build has this fix in it (you reported you were using 6000.4.7f1, which means the bug still exists on this version of Unity).
My recommendation would be to update to 6000.5.3f1 or higher to resolve the underlying issue.
Let me know if this (finally) resolves your issue?
- addedstat:awaiting-responseAwaiting response from author. This label should be added manually.Awaiting response from author. This label should be added manually.and removedstat:reply-neededAwaiting reply from Unity accountAwaiting reply from Unity account
on Sep 25, 2026 To add to that 6000.4 and 6000.5 are out of support already and won't receive further updates so preferably you would move to 6000.6 (although latest 6000.5 should also resolve your issue, just remember that the editor itself won't get further updates)
With that I will close the issue but we can always reopen if this won't fix the issue
- removedstat:awaiting-responseAwaiting response from author. This label should be added manually.Awaiting response from author. This label should be added manually.
on Sep 25, 2026
Description
Infinite hang when reloading a scene contains a manually spawned NetworkObject with a SpriteLibrary and a SpriteResolver
Reproduce Steps
TestCrashwith the following code, and link the prefab from (3) in the inspectorTestCrashis some code thatActual Outcome
After a few attempts, the scene never reloads and the Unity editor hangs forever (has to be force quitted)
Expected Outcome
The scene reloads every 3s
Environment
Additional Context
destroyWithScene: true,InstantiateAndSpawn, if the prefab is added to the scene, the bug doesn't happenHere is a dump of the Main Thread stack when the editor is hanging. The CPU is at 0% at that point. Maybe a lock contention?