256 lines
7.9 KiB
C#
256 lines
7.9 KiB
C#
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<GameObject, bool> originalChunkStates = new Dictionary<GameObject, bool>();
|
|
public HashSet<string> loadedScenes = new HashSet<string>(); // 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<GameObject> 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<GameObject> 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<GameObject> chunksToDisable = new List<GameObject>();
|
|
|
|
foreach (GameObject rootObject in SceneManager.GetSceneByName(sceneName).GetRootGameObjects())
|
|
{
|
|
foreach (Transform child in rootObject.GetComponentsInChildren<Transform>(true))
|
|
{
|
|
if (!chunksToKeep.Contains(child.gameObject) && child.gameObject.activeSelf)
|
|
{
|
|
chunksToDisable.Add(child.gameObject);
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// StartCoroutine(GradualUnloadChunks(chunksToDisable, sceneName));
|
|
}
|
|
|
|
private IEnumerator GradualLoadChunks(List<GameObject> 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<GameObject> 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<GameObject> chunksToUnload)
|
|
{
|
|
StartCoroutine(GradualDisableChunks(chunksToUnload));
|
|
}
|
|
|
|
private IEnumerator GradualDisableChunks(List<GameObject> 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<string> 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<string>(loadedScenes);
|
|
scenesToUnload.ExceptWith(nearbyScenes);
|
|
|
|
foreach (string sceneName in scenesToUnload)
|
|
{
|
|
Debug.Log($"Unloading scene: {sceneName}");
|
|
UnloadSceneAsync(sceneName);
|
|
}
|
|
}
|
|
|
|
public void ReleaseScenes(List<string> nearbyScenes)
|
|
{
|
|
var scenesToUnload = new HashSet<string>(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<GameObject> 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<string> GetLoadedScenes()
|
|
{
|
|
return new HashSet<string>(loadedScenes);
|
|
}
|
|
|
|
} |