using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class DynamicSceneManager : MonoBehaviour { private static DynamicSceneManager _instance; public static DynamicSceneManager GetInstance() { return _instance; } private Dictionary originalChunkStates = new Dictionary(); public HashSet loadedScenes = new HashSet(); // Track loaded scenes private void Awake() { if (_instance == null) { _instance = this; DontDestroyOnLoad(gameObject); // This ensures the object persists across scene loads } else { Destroy(gameObject); // This prevents duplicate instances } //foreach (string nearbyScene in RoomManager.GetInstance()._nearbyRoomSceneNames) //{ // RetainScene(nearbyScene); //} } public void EnableChunks(List chunksToEnable, string sceneName) { Debug.Log($"Starting gradual enabling of {chunksToEnable.Count} chunks for scene {sceneName}"); foreach (var chunk in chunksToEnable) { if (!originalChunkStates.ContainsKey(chunk)) { originalChunkStates[chunk] = chunk.activeSelf; // store initial state } } if (!SceneManager.GetSceneByName(sceneName).isLoaded) { Debug.Log($"Scene {sceneName} is not loaded. Loading it now."); LoadSceneAsync(sceneName, chunksToEnable); } else { Debug.Log($"Scene {sceneName} is already loaded. Enabling valid chunks."); StartCoroutine(GradualEnableChunks(chunksToEnable)); } } public void DisableChunksExcept(List chunksToKeep, string sceneName) { Debug.Log($"Disabling chunks for scene: {sceneName}, keeping {chunksToKeep.Count} chunks."); if (!IsSceneLoaded(sceneName)) { Debug.LogWarning($"Attempted to disable chunks for an unloaded scene: {sceneName}"); return; } List chunksToDisable = new List(); foreach (GameObject rootObject in SceneManager.GetSceneByName(sceneName).GetRootGameObjects()) { foreach (Transform child in rootObject.GetComponentsInChildren(true)) { if (!chunksToKeep.Contains(child.gameObject) && child.gameObject.activeSelf) { chunksToDisable.Add(child.gameObject); } } } // // StartCoroutine(GradualUnloadChunks(chunksToDisable, sceneName)); } private IEnumerator GradualLoadChunks(List chunksToEnable) { foreach (GameObject chunk in chunksToEnable) { if (chunk != null && !chunk.activeSelf) { chunk.SetActive(true); Debug.Log($"Enabled chunk: {chunk.name}"); yield return null; // Distribute work across frames } } } private IEnumerator GradualEnableChunks(List chunksToEnable) { foreach (GameObject chunk in chunksToEnable) { if (chunk != null && !chunk.activeSelf) { if (originalChunkStates.ContainsKey(chunk) && originalChunkStates[chunk]) { chunk.SetActive(true); Debug.Log($"Enabled chunk: {chunk.name}"); } else { Debug.Log($"Skipping chunk {chunk.name} - was originally inactive"); } yield return null; } } } private void GradualUnloadChunks(List chunksToUnload) { StartCoroutine(GradualDisableChunks(chunksToUnload)); } private IEnumerator GradualDisableChunks(List chunksToUnload) { foreach (GameObject chunk in chunksToUnload) { if (chunk != null && chunk.activeSelf) { chunk.SetActive(false); Debug.Log($"Disabled chunk: {chunk.name}"); yield return null; // Spread disabling chunks across frames } } } public void RetainScene(string sceneName) { if (SceneManager.GetSceneByName(sceneName).isLoaded) { Debug.Log($"Scene {sceneName} is already loaded. Skipping RetainScene."); loadedScenes.Add(sceneName); return; } // Add to loadedScenes list and load the scene if (!loadedScenes.Contains(sceneName)) loadedScenes.Add(sceneName); SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive); Debug.Log($"Scene {sceneName} retained successfully."); } public void RetainScenes(List nearbyScenes) { if (nearbyScenes == null || nearbyScenes.Count == 0) { Debug.LogWarning("RetainScenes called with an empty or null list. No scenes retained."); return; } nearbyScenes.RemoveAll(scene => string.IsNullOrWhiteSpace(scene)); // Αφαίρεση άδειων ή μη έγκυρων ονομάτων foreach (string sceneName in nearbyScenes) { if (!loadedScenes.Contains(sceneName)) { RetainScene(sceneName); } else { Debug.Log($"Scene {sceneName} is already loaded. Skipping."); } } // Handle unloading as before var scenesToUnload = new HashSet(loadedScenes); scenesToUnload.ExceptWith(nearbyScenes); foreach (string sceneName in scenesToUnload) { Debug.Log($"Unloading scene: {sceneName}"); UnloadSceneAsync(sceneName); } } public void ReleaseScenes(List nearbyScenes) { var scenesToUnload = new HashSet(loadedScenes); // Retain nearby scenes scenesToUnload.ExceptWith(nearbyScenes); foreach (string sceneName in scenesToUnload) { Debug.Log($"Unloading scene: {sceneName}"); UnloadSceneAsync(sceneName); } } private void LoadSceneAsync(string sceneName, List chunksToEnable = null) { SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive).completed += (op) => { if (op.isDone) { loadedScenes.Add(sceneName); Debug.Log($"Scene {sceneName} successfully loaded."); if (chunksToEnable != null) { StartCoroutine(GradualEnableChunks(chunksToEnable)); } } }; } public void UnloadSceneAsync(string sceneName) { if (string.IsNullOrEmpty(sceneName)) { Debug.LogError("Cannot unload scene: Scene name is null or empty."); return; } if (loadedScenes == null) { Debug.LogError("loadedScenes list is null!"); return; } if (loadedScenes.Contains(sceneName)) { Debug.Log($"Attempting to unload scene: {sceneName}"); SceneManager.UnloadSceneAsync(sceneName).completed += op => { if (op.isDone) { loadedScenes.Remove(sceneName); Debug.Log($"Scene {sceneName} successfully unloaded."); } }; } else { Debug.LogWarning($"Scene {sceneName} is not loaded. Cannot unload."); } } public bool IsSceneLoaded(string sceneName) { return loadedScenes.Contains(sceneName); } public HashSet GetLoadedScenes() { return new HashSet(loadedScenes); } }