// Called on client internal static void OnSceneSwitch(uint sceneIndex, Guid switchSceneGuid, Stream objectStream) { if (!SceneIndexToString.ContainsKey(sceneIndex) || !RegisteredSceneNames.Contains(SceneIndexToString[sceneIndex])) { if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) { NetworkLog.LogWarning("Server requested a scene switch to a non-registered scene"); } return; } s_LastScene = SceneManager.GetActiveScene(); // Move ALL NetworkObjects to the temp scene MoveObjectsToDontDestroyOnLoad(); IsSpawnedObjectsPendingInDontDestroyOnLoad = true; string sceneName = SceneIndexToString[sceneIndex]; var sceneLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single); s_NextSceneName = sceneName; sceneLoad.completed += asyncOp2 => OnSceneLoaded(switchSceneGuid, objectStream); OnSceneSwitchStarted?.Invoke(sceneLoad); }
/// <summary> /// Switches to a scene with a given name. Can only be called from Server /// </summary> /// <param name="sceneName">The name of the scene to switch to</param> public static SceneSwitchProgress SwitchScene(string sceneName) { if (!NetworkManager.Singleton.IsServer) { throw new NotServerException("Only server can start a scene switch"); } if (s_IsSwitching) { if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) { NetworkLog.LogWarning("Scene switch already in progress"); } return(null); } if (!RegisteredSceneNames.Contains(sceneName)) { if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) { NetworkLog.LogWarning($"The scene {sceneName} is not registered as a switchable scene."); } return(null); } NetworkSpawnManager.ServerDestroySpawnedSceneObjects(); //Destroy current scene objects before switching. s_IsSwitching = true; s_LastScene = SceneManager.GetActiveScene(); var switchSceneProgress = new SceneSwitchProgress(); SceneSwitchProgresses.Add(switchSceneProgress.Guid, switchSceneProgress); CurrentSceneSwitchProgressGuid = switchSceneProgress.Guid; // Move ALL NetworkObjects to the temp scene MoveObjectsToDontDestroyOnLoad(); IsSpawnedObjectsPendingInDontDestroyOnLoad = true; // Switch scene AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single); s_NextSceneName = sceneName; sceneLoad.completed += (AsyncOperation asyncOp2) => { OnSceneLoaded(switchSceneProgress.Guid, null); }; switchSceneProgress.SetSceneLoadOperation(sceneLoad); OnSceneSwitchStarted?.Invoke(sceneLoad); return(switchSceneProgress); }
/// <summary> /// Switches to a scene with a given name. Can only be called from Server /// </summary> /// <param name="sceneName">The name of the scene to switch to</param> /// <param name="loadSceneMode">The mode to load the scene (Additive vs Single)</param> /// <returns>SceneSwitchProgress</returns> public SceneSwitchProgress SwitchScene(string sceneName, LoadSceneMode loadSceneMode = LoadSceneMode.Single) { if (!m_NetworkManager.IsServer) { throw new NotServerException("Only server can start a scene switch"); } if (!m_NetworkManager.NetworkConfig.EnableSceneManagement) { //Log message about enabling SceneManagement throw new Exception($"{nameof(NetworkConfig.EnableSceneManagement)} flag is not enabled in the {nameof(NetworkManager)}'s {nameof(NetworkConfig)}. Please set {nameof(NetworkConfig.EnableSceneManagement)} flag to true before calling this method."); } if (s_IsSwitching) { if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) { NetworkLog.LogWarning("Scene switch already in progress"); } return(null); } if (!RegisteredSceneNames.Contains(sceneName)) { if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) { NetworkLog.LogWarning($"The scene {sceneName} is not registered as a switchable scene."); } return(null); } m_NetworkManager.SpawnManager.ServerDestroySpawnedSceneObjects(); //Destroy current scene objects before switching. s_IsSwitching = true; s_LastScene = SceneManager.GetActiveScene(); var switchSceneProgress = new SceneSwitchProgress(m_NetworkManager); SceneSwitchProgresses.Add(switchSceneProgress.Guid, switchSceneProgress); CurrentSceneSwitchProgressGuid = switchSceneProgress.Guid; switchSceneProgress.OnClientLoadedScene += clientId => { OnNotifyServerClientLoadedScene?.Invoke(switchSceneProgress, clientId); }; switchSceneProgress.OnComplete += timedOut => { OnNotifyServerAllClientsLoadedScene?.Invoke(switchSceneProgress, timedOut); using (var buffer = PooledNetworkBuffer.Get()) using (var writer = PooledNetworkWriter.Get(buffer)) { var doneClientIds = switchSceneProgress.DoneClients.ToArray(); var timedOutClientIds = m_NetworkManager.ConnectedClients.Keys.Except(doneClientIds).ToArray(); writer.WriteULongArray(doneClientIds, doneClientIds.Length); writer.WriteULongArray(timedOutClientIds, timedOutClientIds.Length); m_NetworkManager.MessageSender.Send(NetworkManager.Singleton.ServerClientId, NetworkConstants.ALL_CLIENTS_LOADED_SCENE, NetworkChannel.Internal, buffer); } }; // Move ALL NetworkObjects to the temp scene MoveObjectsToDontDestroyOnLoad(); IsSpawnedObjectsPendingInDontDestroyOnLoad = true; // Switch scene AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(sceneName, loadSceneMode); s_NextSceneName = sceneName; sceneLoad.completed += (AsyncOperation asyncOp2) => { OnSceneLoaded(switchSceneProgress.Guid, null); }; switchSceneProgress.SetSceneLoadOperation(sceneLoad); OnSceneSwitchStarted?.Invoke(sceneLoad); return(switchSceneProgress); }