Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using Unity.Netcode;
- using UnityEngine.InputSystem;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine.SceneManagement;
- public class CustomSceneManager : NetworkBehaviour
- {
- public static CustomSceneManager Instance;
- // Public list to assign objects that should not be destroyed on load
- public List<GameObject> dontDestroyOnLoadObjects;
- private List<string> sceneNames = new List<string>();
- private InputAction changeSceneAction;
- private NetworkVariable<int> currentSceneIndex = new NetworkVariable<int>();
- // Add this line to declare the event
- public event System.Action OnSceneLoadedEvent;
- private void Awake()
- {
- if (Instance != null && Instance != this)
- {
- Destroy(gameObject);
- return;
- }
- Instance = this;
- DontDestroyOnLoad(gameObject);
- // Set all objects in the list to not be destroyed on load
- foreach (var obj in dontDestroyOnLoadObjects)
- {
- DontDestroyOnLoad(obj);
- }
- // Populate sceneNames list with scenes from build settings
- for (int i = 0; i < UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings; i++)
- {
- string scenePath = UnityEngine.SceneManagement.SceneUtility.GetScenePathByBuildIndex(i);
- string sceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath);
- sceneNames.Add(sceneName);
- }
- // Setup input action
- var inputActionAsset = new InputActionAsset();
- var gameplayActionMap = inputActionAsset.AddActionMap("Gameplay");
- changeSceneAction = gameplayActionMap.AddAction("ChangeScene", binding: "<Keyboard>/1");
- changeSceneAction.performed += OnChangeScene;
- changeSceneAction.Enable();
- // Initialize current scene index
- currentSceneIndex.Value = sceneNames.IndexOf(UnityEngine.SceneManagement.SceneManager.GetActiveScene().name);
- }
- private void OnEnable()
- {
- NetworkManager.Singleton.SceneManager.OnLoadEventCompleted += OnSceneLoaded;
- }
- private void OnDisable()
- {
- if (NetworkManager.Singleton != null)
- {
- NetworkManager.Singleton.SceneManager.OnLoadEventCompleted -= OnSceneLoaded;
- }
- changeSceneAction.performed -= OnChangeScene;
- changeSceneAction.Disable();
- }
- private void OnChangeScene(InputAction.CallbackContext context)
- {
- if (IsServer && sceneNames.Count > 0)
- {
- ChangeToNextScene();
- }
- }
- [ServerRpc(RequireOwnership = false)]
- private void LoadSceneServerRpc(int sceneIndex)
- {
- if (IsServer)
- {
- LoadSceneAsync(sceneIndex);
- }
- }
- private void LoadSceneAsync(int sceneIndex)
- {
- NetworkManager.Singleton.SceneManager.LoadScene(sceneNames[sceneIndex], LoadSceneMode.Single);
- Debug.Log($"Started loading scene {sceneNames[sceneIndex]} asynchronously");
- }
- private void OnSceneLoaded(string sceneName, LoadSceneMode loadSceneMode, List<ulong> clientsCompleted, List<ulong> clientsTimedOut)
- {
- Debug.Log($"Scene {sceneName} loaded. Clients completed: {clientsCompleted.Count}, Clients timed out: {clientsTimedOut.Count}");
- if (IsServer)
- {
- currentSceneIndex.Value = sceneNames.IndexOf(sceneName);
- NetworkObjChecker.Instance.SpawnInSceneNetworkObjects();
- // Invoke the event
- OnSceneLoadedEvent?.Invoke();
- // Trigger object spawn in SceneobjSpawner
- if (SceneobjSpawner.Instance != null)
- {
- Debug.Log($"Triggering SpawnNetworkedObject for scene {sceneName}");
- SceneobjSpawner.Instance.SpawnNetworkedObject();
- }
- else
- {
- Debug.LogWarning("SceneobjSpawner.Instance is null. Make sure it's set up correctly.");
- }
- }
- }
- private void SpawnNetworkObjects()
- {
- NetworkObject[] sceneObjects = FindObjectsOfType<NetworkObject>();
- foreach (NetworkObject netObj in sceneObjects)
- {
- if (!netObj.IsSpawned)
- {
- netObj.Spawn();
- }
- }
- }
- public override void OnNetworkSpawn()
- {
- if (IsServer)
- {
- foreach (var playerPrefab in dontDestroyOnLoadObjects)
- {
- NetworkManager.Singleton.AddNetworkPrefab(playerPrefab);
- }
- currentSceneIndex.Value = sceneNames.IndexOf(UnityEngine.SceneManagement.SceneManager.GetActiveScene().name);
- }
- }
- public void ChangeScene(string sceneName)
- {
- if (IsServer)
- {
- int sceneIndex = sceneNames.IndexOf(sceneName);
- if (sceneIndex != -1)
- {
- LoadSceneServerRpc(sceneIndex);
- }
- else
- {
- Debug.LogWarning($"Scene {sceneName} not found in build settings.");
- }
- }
- else
- {
- Debug.LogWarning("Scene change requested from a client. Only the server can initiate scene changes.");
- }
- }
- public void ChangeToNextScene()
- {
- if (IsServer && sceneNames.Count > 0)
- {
- int nextSceneIndex = (currentSceneIndex.Value + 1) % sceneNames.Count;
- LoadSceneServerRpc(nextSceneIndex);
- }
- else
- {
- Debug.LogWarning("Scene change requested from a client or no scenes in build. Only the server can initiate scene changes.");
- }
- }
- [ClientRpc]
- public void LoadSceneOnClientsClientRpc(int sceneIndex)
- {
- Debug.Log($"Client received request to load scene index: {sceneIndex}");
- // The NetworkManager will handle the scene loading for clients
- }
- public int CurrentSceneIndex => currentSceneIndex.Value;
- public string GetCurrentSceneName()
- {
- return sceneNames[currentSceneIndex.Value];
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement