internal void ClientSceneMessage(INetworkPlayer player, SceneMessage msg) { if (!Client.IsConnected) { throw new InvalidOperationException("ClientSceneMessage: cannot change network scene while client is disconnected"); } if (string.IsNullOrEmpty(msg.scenePath)) { throw new ArgumentNullException(nameof(msg.scenePath), $"ClientSceneMessage: {nameof(msg.scenePath)} cannot be empty or null"); } if (logger.LogEnabled()) { logger.Log($"ClientSceneMessage: changing scenes from: {ActiveScenePath} to: {msg.scenePath}"); } // Let client prepare for scene change OnClientChangeScene(msg.scenePath, msg.sceneOperation); //Additive are scenes loaded on server and this client is not a host client if (msg.additiveScenes != null && msg.additiveScenes.Length > 0 && Client && !Client.IsLocalClient) { foreach (string scene in msg.additiveScenes) { pendingAdditiveSceneList.Add(scene); } } ApplyOperationAsync(msg.scenePath, msg.sceneOperation).Forget(); }
/// <summary> /// Received message from server to start loading scene or scenes. /// /// <para>Default implementation is to load main activate scene server is using and load any /// other additive scenes in background and notify event handler. If this is not intended /// behavior you need please override this function.</para> /// </summary> /// <param name="player"></param> /// <param name="message"></param> public virtual void ClientStartSceneMessage(INetworkPlayer player, SceneMessage message) { ThrowIfNotClient(); if (string.IsNullOrEmpty(message.MainActivateScene)) { throw new ArgumentException($"[NetworkSceneManager] - SceneLoadStartedMessage: {nameof(message.MainActivateScene)} cannot be empty or null", nameof(message)); } if (logger.LogEnabled()) { logger.Log($"[NetworkSceneManager] - SceneLoadStartedMessage: changing scenes from: {ActiveScenePath} to: {message.MainActivateScene}"); } //Additive are scenes loaded on server and this client is not a host client if (message.AdditiveScenes != null && message.AdditiveScenes.Count > 0 && Client && !Client.IsLocalClient) { for (var sceneIndex = 0; sceneIndex < message.AdditiveScenes.Count; sceneIndex++) { if (string.IsNullOrEmpty(message.AdditiveScenes[sceneIndex])) { continue; } _clientPendingAdditiveSceneLoadingList.Add(message.AdditiveScenes[sceneIndex]); } } // Notify others that client has started to change scenes. OnClientStartedSceneChange?.Invoke(message.MainActivateScene, message.SceneOperation); LoadSceneAsync(message.MainActivateScene, new[] { player }, message.SceneOperation).Forget(); }
internal void ClientSceneMessage(INetworkConnection conn, SceneMessage msg) { if (!Client.IsConnected) { throw new InvalidOperationException("ClientSceneMessage: cannot change network scene while client is disconnected"); } if (string.IsNullOrEmpty(msg.scenePath)) { throw new ArgumentNullException(msg.scenePath, "ClientSceneMessage: " + msg.scenePath + " cannot be empty or null"); } if (logger.LogEnabled()) { logger.Log("ClientSceneMessage: changing scenes from: " + NetworkScenePath + " to:" + msg.scenePath); } // Let client prepare for scene change OnClientChangeScene(msg.scenePath, msg.sceneOperation); //Additive are scenes loaded on server and this client is not a host client if (msg.additiveScenes != null && msg.additiveScenes.Length > 0 && Client && !Client.IsLocalClient) { foreach (string scene in msg.additiveScenes) { pendingAdditiveSceneList.Add(scene); } } StartCoroutine(ApplySceneOperation(msg.scenePath, msg.sceneOperation)); }
/// <summary> /// Allows server to fully load new scene or additive load in another scene. /// </summary> /// <param name="scenePath">The full path to the scenes files or the names of the scenes.</param> /// <param name="players">List of player's we want to send the new scene loading or unloading to.</param> /// <param name="shouldClientLoadOrUnloadNormally">Should client load or unload the scene in normal non additive way</param> /// <param name="sceneOperation">Choose type of scene loading we are doing <see cref="SceneOperation"/>.</param> private void ServerSceneLoading(string scenePath, IEnumerable <INetworkPlayer> players, bool shouldClientLoadOrUnloadNormally, SceneOperation sceneOperation = SceneOperation.Normal, LoadSceneParameters?loadSceneParameters = null) { if (string.IsNullOrEmpty(scenePath)) { throw new ArgumentNullException(nameof(scenePath), "[NetworkSceneManager] - ServerChangeScene: " + nameof(scenePath) + " cannot be empty or null"); } if (logger.LogEnabled()) { logger.Log("[NetworkSceneManager] - ServerChangeScene " + scenePath); } // Let server prepare for scene change logger.Log("[NetworkSceneManager] - OnServerChangeScene"); SetAllClientsNotReady(players); OnServerStartedSceneChange?.Invoke(scenePath, sceneOperation); if (players == null) { throw new ArgumentNullException(nameof(players), "No player's were added to send for information"); } if (!Server.LocalClientActive) { LoadSceneAsync(scenePath, players, sceneOperation, loadSceneParameters).Forget(); } // notify all clients about the new scene if (shouldClientLoadOrUnloadNormally) { sceneOperation = SceneOperation.Normal; } var message = new SceneMessage { MainActivateScene = scenePath, SceneOperation = sceneOperation }; NetworkServer.SendToMany(players, message); }
/// <summary> /// Unload a specific scene from server and clients /// </summary> /// <param name="scene">What scene do we want to tell server and clients to unload.</param> /// <param name="players">The players we want to tell to unload the scene.</param> private void ServerSceneUnLoading(Scene scene, IEnumerable <INetworkPlayer> players) { if (!scene.IsValid()) { throw new ArgumentNullException(nameof(scene), "[NetworkSceneManager] - ServerChangeScene: " + nameof(scene) + " cannot be null"); } if (players == null || !players.Any()) { throw new ArgumentNullException(nameof(players), "[NetworkSceneManager] - list of player's cannot be null or no players."); } if (logger.LogEnabled()) { logger.Log("[NetworkSceneManager] - ServerChangeScene " + scene.name); } // Let server prepare for scene change if (logger.LogEnabled()) { logger.Log("[NetworkSceneManager] - OnServerChangeScene"); } SetAllClientsNotReady(players); OnServerStartedSceneChange?.Invoke(scene.path, SceneOperation.UnloadAdditive); // if not host if (!Server.LocalClientActive) { UnLoadSceneAsync(scene, SceneOperation.UnloadAdditive).Forget(); } // notify all clients about the new scene var msg = new SceneMessage { MainActivateScene = scene.path, SceneOperation = SceneOperation.UnloadAdditive }; NetworkServer.SendToMany(players, msg); }