예제 #1
0
        /// <summary>
        /// Called on clients when a scene has completed loading, when the scene load was initiated by the server.
        /// <para>Non-Additive Scene changes will cause player objects to be destroyed. The default implementation of OnClientSceneChanged in the NetworkSceneManager is to add a player object for the connection if no player object exists.</para>
        /// </summary>
        /// <param name="scenePath">Path of the scene that was just loaded</param>
        /// <param name="sceneOperation">Scene operation that was just  happen</param>
        internal void OnClientSceneChanged(string scenePath, SceneOperation sceneOperation)
        {
            ClientSceneChanged.Invoke(scenePath, sceneOperation);

            if (pendingAdditiveSceneList.Count > 0 && client && !client.IsLocalClient)
            {
                StartCoroutine(ApplySceneOperation(pendingAdditiveSceneList[0], SceneOperation.LoadAdditive));
                pendingAdditiveSceneList.RemoveAt(0);
                return;
            }

            //set ready after scene change has completed
            if (!client.Connection.IsReady)
            {
                SetClientReady();
            }
        }
예제 #2
0
        /// <summary>
        /// Called on clients when a scene has completed loading, when the scene load was initiated by the server.
        /// <para>Non-Additive Scene changes will cause player objects to be destroyed. The default implementation of OnClientSceneChanged in the NetworkSceneManager is to add a player object for the connection if no player object exists.</para>
        /// </summary>
        /// <param name="scenePath">Path of the scene that was just loaded</param>
        /// <param name="sceneOperation">Scene operation that was just  happen</param>
        internal void OnClientSceneChanged(string scenePath, SceneOperation sceneOperation)
        {
            ClientSceneChanged?.Invoke(scenePath, sceneOperation);

            if (pendingAdditiveSceneList.Count > 0 && Client && !Client.IsLocalClient)
            {
                ApplyOperationAsync(pendingAdditiveSceneList[0], SceneOperation.LoadAdditive).Forget();
                pendingAdditiveSceneList.RemoveAt(0);
                return;
            }

            //set ready after scene change has completed
            if (!Client.Player.IsReady)
            {
                SetClientReady();
            }
        }
예제 #3
0
        IEnumerator ApplySceneOperation(string sceneName, SceneOperation sceneOperation = SceneOperation.Normal)
        {
            switch (sceneOperation)
            {
            case SceneOperation.Normal:
                NetworkSceneName = sceneName;
                asyncOperation   = SceneManager.LoadSceneAsync(sceneName);

                //If non host client. Wait for server to finish scene change
                if (client && client.Active && !client.IsLocalClient)
                {
                    asyncOperation.allowSceneActivation = false;
                }

                yield return(asyncOperation);

                break;

            case SceneOperation.LoadAdditive:
                // Ensure additive scene is not already loaded since we don't know which was passed in the Scene message
                if (!SceneManager.GetSceneByName(sceneName).IsValid() && !SceneManager.GetSceneByPath(sceneName).IsValid())
                {
                    yield return(SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive));
                }
                else
                {
                    logger.LogWarning($"Scene {sceneName} is already loaded");
                }
                break;

            case SceneOperation.UnloadAdditive:
                // Ensure additive scene is actually loaded since we don't know which was passed in the Scene message
                if (SceneManager.GetSceneByName(sceneName).IsValid() || SceneManager.GetSceneByPath(sceneName).IsValid())
                {
                    yield return(SceneManager.UnloadSceneAsync(sceneName, UnloadSceneOptions.UnloadAllEmbeddedSceneObjects));
                }
                else
                {
                    logger.LogWarning($"Cannot unload {sceneName} with UnloadAdditive operation");
                }
                break;
            }

            FinishLoadScene(sceneName, sceneOperation);
        }
예제 #4
0
        internal void FinishLoadScene(string sceneName, SceneOperation sceneOperation)
        {
            // host mode?
            if (client && client.IsLocalClient)
            {
                logger.Log("Finished loading scene in host mode.");

                if (client.Connection != null && sceneOperation == SceneOperation.Normal)
                {
                    client.OnAuthenticated(client.Connection);
                }

                // server scene was loaded. now spawn all the objects
                server.ActivateHostScene();

                // call OnServerSceneChanged
                OnServerSceneChanged(sceneName, sceneOperation);

                if (client.IsConnected)
                {
                    // let client know that we changed scene
                    OnClientSceneChanged(sceneName, sceneOperation);
                }
            }
            // server-only mode?
            else if (server && server.Active)
            {
                logger.Log("Finished loading scene in server-only mode.");

                server.SpawnObjects();
                OnServerSceneChanged(sceneName, sceneOperation);
            }
            // client-only mode?
            else if (client && client.Active)
            {
                logger.Log("Finished loading scene in client-only mode.");

                if (client.Connection != null && sceneOperation == SceneOperation.Normal)
                {
                    client.OnAuthenticated(client.Connection);
                }

                OnClientSceneChanged(sceneName, sceneOperation);
            }
        }
예제 #5
0
        public static SceneOperation LoadSceneAsync(int name)
        {
            mIns.isLoadingLevel = true;
            GameSceneInfo s;

            mIns.TrygetValue(name, out s);
            mIns.nextScene = s;
#if UNITY_5_3 || UNITY_5_4 || UNITY_5_5 || UNITY_5_6
            SceneOperation sceneop = SceneManager.LoadSceneAsync(name);
            sceneop.ScenePath       = s.name.ToLower() + ".unity";
            sceneop.loadedSceneName = s.name;
            return(sceneop);
#else
            SceneOperation sceneop = Application.LoadLevelAsync(name);
            sceneop.ScenePath       = s.name.ToLower() + ".unity";
            sceneop.loadedSceneName = s.name;
            return(sceneop);
#endif
        }
예제 #6
0
        private void LoadScene()
        {
            if (!this.isABMode)
            {
                SceneOperation asyOp = GameSceneCtr.LoadSceneAsync(Path.GetFileNameWithoutExtension(this.loadingpkg.BundleName));
                asyOp.DisableScene();
                this._AsyncOpation = asyOp;

                this._PushTaskAndExcute(this.loadingpkg, asyOp);
            }
            else
            {
                ///需要异步预实例化
                SceneOperation asyOp = GameSceneCtr.LoadSceneAsync(this._BundleRef.LoadName);
                asyOp.DisableScene();

                this._AsyncOpation = asyOp;
                this._PushTaskAndExcute(this.loadingpkg, asyOp);
            }
        }
예제 #7
0
        internal void FinishLoadScene(string scenePath, SceneOperation sceneOperation)
        {
            // host mode?
            if (Client && Client.IsLocalClient)
            {
                if (logger.LogEnabled())
                {
                    logger.Log("Host: " + sceneOperation.ToString() + " operation for scene: " + scenePath);
                }

                // call OnServerSceneChanged
                OnServerSceneChanged(scenePath, sceneOperation);

                if (Client.IsConnected)
                {
                    // let client know that we changed scene
                    OnClientSceneChanged(scenePath, sceneOperation);
                }
            }
            // server-only mode?
            else if (Server && Server.Active)
            {
                if (logger.LogEnabled())
                {
                    logger.Log("Server: " + sceneOperation.ToString() + " operation for scene: " + scenePath);
                }

                OnServerSceneChanged(scenePath, sceneOperation);
            }
            // client-only mode?
            else if (Client && Client.Active && !Client.IsLocalClient)
            {
                if (logger.LogEnabled())
                {
                    logger.Log("Client: " + sceneOperation.ToString() + " operation for scene: " + scenePath);
                }

                OnClientSceneChanged(scenePath, sceneOperation);
            }
        }
예제 #8
0
        /// <summary>
        ///     Finish loading the scene.
        /// </summary>
        /// <param name="scene">The scene that is finishing.</param>
        /// <param name="sceneOperation">Choose type of scene loading we are doing <see cref="SceneOperation"/>.</param>
        /// <param name="players">List of players we are adding to this scene.</param>
        internal void CompleteLoadingScene(Scene scene, SceneOperation sceneOperation, IEnumerable <INetworkPlayer> players = null)
        {
            // If server mode call this to make sure scene finishes loading
            if (Server && Server.Active)
            {
                if (logger.LogEnabled())
                {
                    logger.Log("[NetworkSceneManager] - Host: " + sceneOperation + " operation for scene: " +
                               scene.path);
                }

                // call OnServerSceneChanged
                OnServerFinishedSceneLoad(scene, sceneOperation);

                if (_serverSceneData.ContainsKey(scene))
                {
                    // Check to make sure this scene was not already loaded. If it was let's clear old data on it.
                    logger.Log(
                        $"[NetworkSceneManager] - Scene load operation: {SceneOperation.Normal}. Scene was already loaded once before. Clearing scene related data in {_serverSceneData}.");

                    _serverSceneData.Remove(scene);
                }

                _serverSceneData.Add(scene, new HashSet <INetworkPlayer>(players ?? Server.Players));
            }

            // If client let's call this to finish client scene loading too
            if (Client && Client.Active)
            {
                if (logger.LogEnabled())
                {
                    logger.Log("[NetworkSceneManager] - Client: " + sceneOperation + " operation for scene: " +
                               scene.path);
                }

                OnClientSceneLoadFinished(scene, sceneOperation);
            }
        }
예제 #9
0
        /// <summary>
        /// This causes the server to switch scenes and sets the networkSceneName.
        /// <para>Clients that connect to this server will automatically switch to this scene. This automatically sets clients to be not-ready. The clients must call Ready() again to participate in the new scene.</para>
        /// </summary>
        /// <param name="newSceneName"></param>
        /// <param name="operation"></param>
        public void ChangeServerScene(string newSceneName, SceneOperation sceneOperation = SceneOperation.Normal)
        {
            if (string.IsNullOrEmpty(newSceneName))
            {
                throw new ArgumentNullException(nameof(newSceneName), "ServerChangeScene: " + nameof(newSceneName) + " cannot be empty or null");
            }

            if (logger.LogEnabled())
            {
                logger.Log("ServerChangeScene " + newSceneName);
            }
            server.SetAllClientsNotReady();

            // Let server prepare for scene change
            OnServerChangeScene(newSceneName, sceneOperation);

            StartCoroutine(ApplySceneOperation(newSceneName, sceneOperation));

            // notify all clients about the new scene
            server.SendToAll(new SceneMessage {
                sceneName = newSceneName, sceneOperation = sceneOperation
            });
        }
예제 #10
0
        public SceneOperation sceneOperation; // Normal = 0, LoadAdditive = 1, UnloadAdditive = 2

        public void Deserialize(NetworkReader reader)
        {
            sceneName      = reader.ReadString();
            sceneOperation = (SceneOperation)reader.ReadByte();
        }
예제 #11
0
 public void Button_Back()
 {
     StartCoroutine(SceneOperation.GetInstance().AnimExit(sceneItems, 1));
 }
예제 #12
0
 void OnClientSceneChanged(string scenePath, SceneOperation sceneOperation)
 {
     PrepareToSpawnSceneObjects();
 }
예제 #13
0
        /// <summary>
        ///     Internal usage to apply loading a scene correctly. Other api will be available to override things.
        /// </summary>
        /// <param name="scenePath">The full path to the scene file or the name of the scene.</param>
        /// <param name="players">List of player's we want to track which scene they are in.</param>
        /// <param name="sceneOperation">Choose type of scene loading we are doing <see cref="SceneOperation"/>.</param>
        /// <param name="sceneLoadParameters">What settings should we be using for physics scene loading.</param>
        private UniTask LoadSceneAsync(string scenePath, IEnumerable <INetworkPlayer> players = null, SceneOperation sceneOperation = SceneOperation.Normal, LoadSceneParameters?sceneLoadParameters = null)
        {
            switch (sceneOperation)
            {
            case SceneOperation.Normal:
                return(LoadSceneNormalAsync(scenePath, sceneLoadParameters));

            case SceneOperation.LoadAdditive:
                return(LoadSceneAdditiveAsync(scenePath, players, sceneLoadParameters));

            case SceneOperation.UnloadAdditive:
                return(UnLoadSceneAdditiveAsync(scenePath));

            default:
                throw new InvalidEnumArgumentException(nameof(sceneOperation), (int)sceneOperation,
                                                       typeof(SceneOperation));
            }
        }
예제 #14
0
 public void Deserialize(NetworkReader reader)
 {
     sceneName      = reader.ReadString();
     sceneOperation = (SceneOperation)reader.ReadByte();
     customHandling = reader.ReadBoolean();
 }
예제 #15
0
        private void OnFinishedSceneChange(Scene scene, SceneOperation sceneOperation)
        {
            Server.World.RemoveDestroyedObjects();

            SpawnOrActivate();
        }
예제 #16
0
 /// <summary>
 /// Called from ChangeServerScene immediately before NetworkSceneManager's LoadSceneAsync is executed
 /// <para>This allows server to do work / cleanup / prep before the scene changes.</para>
 /// </summary>
 /// <param name="newSceneName">Name of the scene that's about to be loaded</param>
 internal void OnServerChangeScene(string newSceneName, SceneOperation operation)
 {
     ServerChangeScene.Invoke(newSceneName, operation);
 }
예제 #17
0
        /// <summary>
        /// Called from ChangeServerScene immediately before NetworkSceneManager's LoadSceneAsync is executed
        /// <para>This allows server to do work / cleanup / prep before the scene changes.</para>
        /// </summary>
        /// <param name="scenePath">Path of the scene that's about to be loaded</param>
        internal void OnServerChangeScene(string scenePath, SceneOperation operation)
        {
            logger.Log("OnServerChangeScene");

            ServerChangeScene?.Invoke(scenePath, operation);
        }
예제 #18
0
 /// <summary>
 /// Called from ClientChangeScene immediately before SceneManager.LoadSceneAsync is executed
 /// <para>This allows client to do work / cleanup / prep before the scene changes.</para>
 /// </summary>
 /// <param name="newSceneName">Name of the scene that's about to be loaded</param>
 /// <param name="sceneOperation">Scene operation that's about to happen</param>
 internal void OnClientChangeScene(string sceneName, SceneOperation sceneOperation)
 {
     ClientChangeScene.Invoke(sceneName, sceneOperation);
 }
예제 #19
0
 public void Button_Main(int choosenScene)
 {
     StartCoroutine(SceneOperation.GetInstance().AnimExit(sceneItems, choosenScene));
 }
예제 #20
0
 public override void OnClientChangeScene(string newSceneName, SceneOperation sceneOperation,
                                          bool customHandling)
 {
     OnClientChangeSceneEvent();
     base.OnClientChangeScene(newSceneName, sceneOperation, customHandling);
 }
예제 #21
0
 void OnServerSceneChanged(string scenePath, SceneOperation sceneOperation)
 {
     SpawnOrActivate();
 }
예제 #22
0
 void OnServerChangeScene(string scenePath, SceneOperation sceneOperation)
 {
     SetAllClientsNotReady();
 }
예제 #23
0
 public override void OnClientChangeScene(string newSceneName, SceneOperation sceneOperation, bool customHandling)
 {
     LevelTransitionLoader.instance.PlayTransitionFadeIn();
     base.OnClientChangeScene(newSceneName, sceneOperation, customHandling);
 }
예제 #24
0
        /// <summary>
        /// Called on the server when a scene is completed loaded, when the scene load was initiated by the server with ChangeServerScene().
        /// </summary>
        /// <param name="sceneName">The name of the new scene.</param>
        internal void OnServerSceneChanged(string sceneName, SceneOperation operation)
        {
            server.SendToAll(new SceneReadyMessage());

            ServerSceneChanged.Invoke(sceneName, operation);
        }
예제 #25
0
 /// <summary>
 /// Called from ClientChangeScene immediately before SceneManager.LoadSceneAsync is executed
 /// <para>This allows client to do work / cleanup / prep before the scene changes.</para>
 /// </summary>
 /// <param name="scenePath">Path of the scene that's about to be loaded</param>
 /// <param name="sceneOperation">Scene operation that's about to happen</param>
 internal void OnClientChangeScene(string scenePath, SceneOperation sceneOperation)
 {
     ClientChangeScene?.Invoke(scenePath, sceneOperation);
 }
예제 #26
0
 public void ClientChangeScene(string sceneName, SceneOperation sceneOperation, bool customHandling)
 {
     ClientChangeCalled++;
 }
예제 #27
0
        /// <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);
        }
예제 #28
0
        internal void ClientChangeScene(string newSceneName, SceneOperation sceneOperation = SceneOperation.Normal, bool customHandling = false)
        {
            if (string.IsNullOrEmpty(newSceneName))
            {
                Debug.LogError("ClientChangeScene empty scene name");
                return;
            }

            if (LogFilter.Debug)
            {
                Debug.Log("ClientChangeScene newSceneName:" + newSceneName + " networkSceneName:" + networkSceneName);
            }

            // vis2k: pause message handling while loading scene. otherwise we will process messages and then lose all
            // the state as soon as the load is finishing, causing all kinds of bugs because of missing state.
            // (client may be null after StopClient etc.)
            if (LogFilter.Debug)
            {
                Debug.Log("ClientChangeScene: pausing handlers while scene is loading to avoid data loss after scene was loaded.");
            }
            // Let client prepare for scene change
            OnClientChangeScene(newSceneName, sceneOperation, customHandling);

            // scene handling will happen in overrides of OnClientChangeScene and/or OnClientSceneChanged
            if (customHandling)
            {
                FinishLoadScene();
                return;
            }

            switch (sceneOperation)
            {
            case SceneOperation.Normal:
                loadingSceneAsync = SceneManager.LoadSceneAsync(newSceneName);
                break;

            case SceneOperation.LoadAdditive:
                if (!SceneManager.GetSceneByName(newSceneName).IsValid())
                {
                    loadingSceneAsync = SceneManager.LoadSceneAsync(newSceneName, LoadSceneMode.Additive);
                }
                else
                {
                    Debug.LogWarningFormat("Scene {0} is already loaded", newSceneName);
                }
                break;

            case SceneOperation.UnloadAdditive:
                if (SceneManager.GetSceneByName(newSceneName).IsValid())
                {
                    if (SceneManager.GetSceneByName(newSceneName) != null)
                    {
                        loadingSceneAsync = SceneManager.UnloadSceneAsync(newSceneName, UnloadSceneOptions.UnloadAllEmbeddedSceneObjects);
                    }
                }
                else
                {
                    Debug.LogWarning("Cannot unload the active scene with UnloadAdditive operation");
                }
                break;
            }

            // don't change the client's current networkSceneName when loading additive scene content
            if (sceneOperation == SceneOperation.Normal)
            {
                networkSceneName = newSceneName;
            }
        }
예제 #29
0
 /// <summary>
 /// Called from ClientChangeScene immediately before SceneManager.LoadSceneAsync is executed
 /// <para>This allows client to do work / cleanup / prep before the scene changes.</para>
 /// </summary>
 /// <param name="newSceneName">Name of the scene that's about to be loaded</param>
 /// <param name="sceneOperation">Scene operation that's about to happen</param>
 /// <param name="customHandling">true to indicate that scene loading will be handled through overrides</param>
 public override void OnClientChangeScene(string newSceneName, SceneOperation sceneOperation, bool customHandling)
 {
 }
 /// <summary>
 /// Called from ChangeServerScene immediately before NetworkSceneManager's LoadSceneAsync is executed
 /// <para>This allows server to do work / cleanup / prep before the scene changes.</para>
 /// </summary>
 /// <param name="scenePath">Path of the scene that's about to be loaded</param>
 internal void OnServerChangeScene(string scenePath, SceneOperation operation)
 {
     ServerChangeScene.Invoke(scenePath, operation);
 }