| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 | 
							- using System.Collections;
 
- using System.Collections.Generic;
 
- using UnityEngine;
 
- using UnityEngine.SceneManagement;
 
- /*
 
- 	Documentation: https://mirror-networking.gitbook.io/docs/components/network-manager
 
- 	API Reference: https://mirror-networking.com/docs/api/Mirror.NetworkManager.html
 
- */
 
- namespace Mirror.Examples.MultipleAdditiveScenes
 
- {
 
-     [AddComponentMenu("")]
 
-     public class MultiSceneNetManager : NetworkManager
 
-     {
 
-         [Header("Spawner Setup")]
 
-         [Tooltip("Reward Prefab for the Spawner")]
 
-         public GameObject rewardPrefab;
 
-         [Header("MultiScene Setup")]
 
-         public int instances = 3;
 
-         [Scene]
 
-         public string gameScene;
 
-         // This is set true after server loads all subscene instances
 
-         bool subscenesLoaded;
 
-         // subscenes are added to this list as they're loaded
 
-         readonly List<Scene> subScenes = new List<Scene>();
 
-         // Sequential index used in round-robin deployment of players into instances and score positioning
 
-         int clientIndex;
 
-         #region Server System Callbacks
 
-         /// <summary>
 
-         /// Called on the server when a client adds a new player with NetworkClient.AddPlayer.
 
-         /// <para>The default implementation for this function creates a new player object from the playerPrefab.</para>
 
-         /// </summary>
 
-         /// <param name="conn">Connection from client.</param>
 
-         public override void OnServerAddPlayer(NetworkConnectionToClient conn)
 
-         {
 
-             StartCoroutine(OnServerAddPlayerDelayed(conn));
 
-         }
 
-         // This delay is mostly for the host player that loads too fast for the
 
-         // server to have subscenes async loaded from OnStartServer ahead of it.
 
-         IEnumerator OnServerAddPlayerDelayed(NetworkConnectionToClient conn)
 
-         {
 
-             // wait for server to async load all subscenes for game instances
 
-             while (!subscenesLoaded)
 
-                 yield return null;
 
-             // Send Scene message to client to additively load the game scene
 
-             conn.Send(new SceneMessage { sceneName = gameScene, sceneOperation = SceneOperation.LoadAdditive });
 
-             // Wait for end of frame before adding the player to ensure Scene Message goes first
 
-             yield return new WaitForEndOfFrame();
 
-             base.OnServerAddPlayer(conn);
 
-             PlayerScore playerScore = conn.identity.GetComponent<PlayerScore>();
 
-             playerScore.playerNumber = clientIndex;
 
-             playerScore.scoreIndex = clientIndex / subScenes.Count;
 
-             playerScore.matchIndex = clientIndex % subScenes.Count;
 
-             // Do this only on server, not on clients
 
-             // This is what allows the NetworkSceneChecker on player and scene objects
 
-             // to isolate matches per scene instance on server.
 
-             if (subScenes.Count > 0)
 
-                 SceneManager.MoveGameObjectToScene(conn.identity.gameObject, subScenes[clientIndex % subScenes.Count]);
 
-             clientIndex++;
 
-         }
 
-         #endregion
 
-         #region Start & Stop Callbacks
 
-         /// <summary>
 
-         /// This is invoked when a server is started - including when a host is started.
 
-         /// <para>StartServer has multiple signatures, but they all cause this hook to be called.</para>
 
-         /// </summary>
 
-         public override void OnStartServer()
 
-         {
 
-             StartCoroutine(ServerLoadSubScenes());
 
-         }
 
-         // We're additively loading scenes, so GetSceneAt(0) will return the main "container" scene,
 
-         // therefore we start the index at one and loop through instances value inclusively.
 
-         // If instances is zero, the loop is bypassed entirely.
 
-         IEnumerator ServerLoadSubScenes()
 
-         {
 
-             for (int index = 1; index <= instances; index++)
 
-             {
 
-                 yield return SceneManager.LoadSceneAsync(gameScene, new LoadSceneParameters { loadSceneMode = LoadSceneMode.Additive, localPhysicsMode = LocalPhysicsMode.Physics3D });
 
-                 Scene newScene = SceneManager.GetSceneAt(index);
 
-                 subScenes.Add(newScene);
 
-                 Spawner.InitialSpawn(newScene);
 
-             }
 
-             subscenesLoaded = true;
 
-         }
 
-         /// <summary>
 
-         /// This is called when a server is stopped - including when a host is stopped.
 
-         /// </summary>
 
-         public override void OnStopServer()
 
-         {
 
-             NetworkServer.SendToAll(new SceneMessage { sceneName = gameScene, sceneOperation = SceneOperation.UnloadAdditive });
 
-             StartCoroutine(ServerUnloadSubScenes());
 
-             clientIndex = 0;
 
-         }
 
-         // Unload the subScenes and unused assets and clear the subScenes list.
 
-         IEnumerator ServerUnloadSubScenes()
 
-         {
 
-             for (int index = 0; index < subScenes.Count; index++)
 
-                 yield return SceneManager.UnloadSceneAsync(subScenes[index]);
 
-             subScenes.Clear();
 
-             subscenesLoaded = false;
 
-             yield return Resources.UnloadUnusedAssets();
 
-         }
 
-         /// <summary>
 
-         /// This is called when a client is stopped.
 
-         /// </summary>
 
-         public override void OnStopClient()
 
-         {
 
-             // make sure we're not in host mode
 
-             if (mode == NetworkManagerMode.ClientOnly)
 
-                 StartCoroutine(ClientUnloadSubScenes());
 
-         }
 
-         // Unload all but the active scene, which is the "container" scene
 
-         IEnumerator ClientUnloadSubScenes()
 
-         {
 
-             for (int index = 0; index < SceneManager.sceneCount; index++)
 
-             {
 
-                 if (SceneManager.GetSceneAt(index) != SceneManager.GetActiveScene())
 
-                     yield return SceneManager.UnloadSceneAsync(SceneManager.GetSceneAt(index));
 
-             }
 
-         }
 
-         #endregion
 
-     }
 
- }
 
 
  |