SceneLoaderWrapper.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using System;
  2. using Unity.Netcode;
  3. using UnityEngine;
  4. using UnityEngine.SceneManagement;
  5. namespace Unity.Multiplayer.Samples.Utilities
  6. {
  7. //场景切换管理。SceneManager、NetworkSceneManager
  8. public class SceneLoaderWrapper : NetworkBehaviour
  9. {
  10. //[SerializeField]
  11. //ClientLoadingScreen m_ClientLoadingScreen;
  12. //[SerializeField]
  13. //LoadingProgressManager m_LoadingProgressManager;
  14. //是否开启了场景管理
  15. bool IsNetworkSceneManagementEnabled => NetworkManager != null && NetworkManager.SceneManager != null && NetworkManager.NetworkConfig.EnableSceneManagement;
  16. public static SceneLoaderWrapper Instance { get; protected set; }
  17. public virtual void Awake()
  18. {
  19. if (Instance != null && Instance != this)
  20. {
  21. Destroy(gameObject);
  22. }
  23. else
  24. {
  25. Instance = this;
  26. }
  27. DontDestroyOnLoad(this);
  28. }
  29. public virtual void Start()
  30. {
  31. SceneManager.sceneLoaded += OnSceneLoaded;
  32. }
  33. public override void OnDestroy()
  34. {
  35. SceneManager.sceneLoaded -= OnSceneLoaded;
  36. base.OnDestroy();
  37. }
  38. public override void OnNetworkDespawn()
  39. {
  40. if (NetworkManager != null && NetworkManager.SceneManager != null)
  41. {
  42. NetworkManager.SceneManager.OnSceneEvent -= OnSceneEvent;
  43. }
  44. }
  45. //添加场景加载回调
  46. public virtual void AddOnSceneEventCallback()
  47. {
  48. if (IsNetworkSceneManagementEnabled)
  49. {
  50. NetworkManager.SceneManager.OnSceneEvent += OnSceneEvent;
  51. }
  52. }
  53. //异步加载场景,可以用SceneManager(Unity自己的),也可以用NetworkSceneManager(NetCode)
  54. public virtual void LoadScene(string sceneName, bool useNetworkSceneManager, LoadSceneMode loadSceneMode = LoadSceneMode.Single)
  55. {
  56. if (useNetworkSceneManager)
  57. {
  58. //使用NetworkSceneManager加载场景
  59. if(IsSpawned && IsNetworkSceneManagementEnabled && !NetworkManager.ShutdownInProgress)
  60. {
  61. if (NetworkManager.IsServer)
  62. {
  63. //必须服务端,才能加载场景
  64. NetworkManager.SceneManager.LoadScene(sceneName, loadSceneMode);
  65. }
  66. }
  67. }
  68. else
  69. {
  70. //使用SceneManager异步加载场景
  71. var loadOperation = SceneManager.LoadSceneAsync(sceneName, loadSceneMode);
  72. if (loadSceneMode == LoadSceneMode.Single)
  73. {
  74. //m_ClientLoadingScreen.StartLoadingScreen(sceneName);
  75. //m_LoadingProgressManager.LocalLoadOperation = loadOperation;
  76. }
  77. }
  78. }
  79. //Unity的场景切换成功
  80. void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
  81. {
  82. if (!IsSpawned || NetworkManager.ShutdownInProgress)
  83. {
  84. //m_ClientLoadingScreen.StopLoadingScreen();
  85. }
  86. }
  87. //收到其他客户端发来的场景切换消息
  88. void OnSceneEvent(SceneEvent sceneEvent)
  89. {
  90. switch(sceneEvent.SceneEventType)
  91. {
  92. case SceneEventType.Load:
  93. //服务端通知客户端切换场景
  94. if(NetworkManager.IsClient)
  95. {
  96. //客户端进行UI显示
  97. if(sceneEvent.LoadSceneMode == LoadSceneMode.Single)
  98. {
  99. //m_ClientLoadingScreen.StartLoadingScreen(sceneEvent.SceneName);
  100. //m_LoadingProgressManager.LocalLoadOperation = sceneEvent.AsyncOperation;
  101. }
  102. else
  103. {
  104. //m_ClientLoadingScreen.UpdateLoadingScreen(sceneEvent.SceneName);
  105. //m_LoadingProgressManager.LocalLoadOperation = sceneEvent.AsyncOperation;
  106. }
  107. }
  108. break;
  109. case SceneEventType.LoadEventCompleted:
  110. //服务端通知客户端,所有的客户端都加载成功
  111. if(NetworkManager.IsClient)
  112. {
  113. //m_ClientLoadingScreen.StopLoadingScreen();
  114. //m_LoadingProgressManager.ResetLocalProgress();
  115. }
  116. break;
  117. case SceneEventType.Synchronize:
  118. {
  119. //服务端通知客户端,开始同步场景加载进度
  120. if(NetworkManager.IsClient && !NetworkManager.IsHost)
  121. {
  122. //只有Client才执行(非Host)
  123. //卸载其他场景
  124. UnloadAdditiveScenes();
  125. }
  126. break;
  127. }
  128. case SceneEventType.SynchronizeComplete:
  129. // 客户端通知服务端,场景同步完成
  130. if(NetworkManager.IsServer)
  131. {
  132. //服务端通知客户端隐藏Loading界面
  133. StopLoadingScreenClientRpc(new ClientRpcParams { Send = new ClientRpcSendParams { TargetClientIds = new[] { sceneEvent.ClientId } } });
  134. }
  135. break;
  136. }
  137. }
  138. //Unity卸载其他场景(非ActiveScene)
  139. void UnloadAdditiveScenes()
  140. {
  141. var activeScene = SceneManager.GetActiveScene();
  142. for (var i = 0; i < SceneManager.sceneCount; i++)
  143. {
  144. var scene = SceneManager.GetSceneAt(i);
  145. if (scene.isLoaded && scene != activeScene)
  146. {
  147. SceneManager.UnloadSceneAsync(scene);
  148. }
  149. }
  150. }
  151. //服务端通知客户端隐藏Loading界面
  152. [ClientRpc]
  153. void StopLoadingScreenClientRpc(ClientRpcParams clientRpcParams = default)
  154. {
  155. //m_ClientLoadingScreen.StopLoadingScreen();
  156. }
  157. }
  158. }