using System; using Unity.Netcode; using UnityEngine; using UnityEngine.SceneManagement; namespace Unity.Multiplayer.Samples.Utilities { //场景切换管理。SceneManager、NetworkSceneManager public class SceneLoaderWrapper : NetworkBehaviour { //[SerializeField] //ClientLoadingScreen m_ClientLoadingScreen; //[SerializeField] //LoadingProgressManager m_LoadingProgressManager; //是否开启了场景管理 bool IsNetworkSceneManagementEnabled => NetworkManager != null && NetworkManager.SceneManager != null && NetworkManager.NetworkConfig.EnableSceneManagement; public static SceneLoaderWrapper Instance { get; protected set; } public virtual void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); } else { Instance = this; } DontDestroyOnLoad(this); } public virtual void Start() { SceneManager.sceneLoaded += OnSceneLoaded; } public override void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; base.OnDestroy(); } public override void OnNetworkDespawn() { if (NetworkManager != null && NetworkManager.SceneManager != null) { NetworkManager.SceneManager.OnSceneEvent -= OnSceneEvent; } } //添加场景加载回调 public virtual void AddOnSceneEventCallback() { if (IsNetworkSceneManagementEnabled) { NetworkManager.SceneManager.OnSceneEvent += OnSceneEvent; } } //异步加载场景,可以用SceneManager(Unity自己的),也可以用NetworkSceneManager(NetCode) public virtual void LoadScene(string sceneName, bool useNetworkSceneManager, LoadSceneMode loadSceneMode = LoadSceneMode.Single) { if (useNetworkSceneManager) { //使用NetworkSceneManager加载场景 if(IsSpawned && IsNetworkSceneManagementEnabled && !NetworkManager.ShutdownInProgress) { if (NetworkManager.IsServer) { //必须服务端,才能加载场景 NetworkManager.SceneManager.LoadScene(sceneName, loadSceneMode); } } } else { //使用SceneManager异步加载场景 var loadOperation = SceneManager.LoadSceneAsync(sceneName, loadSceneMode); if (loadSceneMode == LoadSceneMode.Single) { //m_ClientLoadingScreen.StartLoadingScreen(sceneName); //m_LoadingProgressManager.LocalLoadOperation = loadOperation; } } } //Unity的场景切换成功 void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode) { if (!IsSpawned || NetworkManager.ShutdownInProgress) { //m_ClientLoadingScreen.StopLoadingScreen(); } } //收到其他客户端发来的场景切换消息 void OnSceneEvent(SceneEvent sceneEvent) { switch(sceneEvent.SceneEventType) { case SceneEventType.Load: //服务端通知客户端切换场景 if(NetworkManager.IsClient) { //客户端进行UI显示 if(sceneEvent.LoadSceneMode == LoadSceneMode.Single) { //m_ClientLoadingScreen.StartLoadingScreen(sceneEvent.SceneName); //m_LoadingProgressManager.LocalLoadOperation = sceneEvent.AsyncOperation; } else { //m_ClientLoadingScreen.UpdateLoadingScreen(sceneEvent.SceneName); //m_LoadingProgressManager.LocalLoadOperation = sceneEvent.AsyncOperation; } } break; case SceneEventType.LoadEventCompleted: //服务端通知客户端,所有的客户端都加载成功 if(NetworkManager.IsClient) { //m_ClientLoadingScreen.StopLoadingScreen(); //m_LoadingProgressManager.ResetLocalProgress(); } break; case SceneEventType.Synchronize: { //服务端通知客户端,开始同步场景加载进度 if(NetworkManager.IsClient && !NetworkManager.IsHost) { //只有Client才执行(非Host) //卸载其他场景 UnloadAdditiveScenes(); } break; } case SceneEventType.SynchronizeComplete: // 客户端通知服务端,场景同步完成 if(NetworkManager.IsServer) { //服务端通知客户端隐藏Loading界面 StopLoadingScreenClientRpc(new ClientRpcParams { Send = new ClientRpcSendParams { TargetClientIds = new[] { sceneEvent.ClientId } } }); } break; } } //Unity卸载其他场景(非ActiveScene) void UnloadAdditiveScenes() { var activeScene = SceneManager.GetActiveScene(); for (var i = 0; i < SceneManager.sceneCount; i++) { var scene = SceneManager.GetSceneAt(i); if (scene.isLoaded && scene != activeScene) { SceneManager.UnloadSceneAsync(scene); } } } //服务端通知客户端隐藏Loading界面 [ClientRpc] void StopLoadingScreenClientRpc(ClientRpcParams clientRpcParams = default) { //m_ClientLoadingScreen.StopLoadingScreen(); } } }