ProjectDDD/Assets/_DDD/_Scripts/GameFramework/SceneManager.cs

117 lines
3.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
namespace DDD
{
public enum SceneType
{
Entry = 0,
Restaurant = 1,
Voyage = 2
}
public class SceneManager : Singleton<SceneManager>, IManager
{
private Dictionary<SceneType, SceneInstance> _loadedScenes;
public Action<Scene> OnSceneChanged;
public void Init()
{
Array sceneTypeArray = Enum.GetValues(typeof(SceneType));
_loadedScenes = new Dictionary<SceneType, SceneInstance>(sceneTypeArray.Length);
}
public async void PostInit()
{
try
{
foreach (SceneType sceneType in Enum.GetValues(typeof(SceneType)))
{
if (sceneType == SceneType.Entry) continue;
var sceneInstance = await AssetManager.LoadScene(sceneType.ToString());
if (sceneInstance.Scene.IsValid())
{
_loadedScenes[sceneType] = sceneInstance;
foreach (var go in sceneInstance.Scene.GetRootGameObjects())
{
go.SetActive(false);
}
}
}
}
catch (Exception e)
{
Debug.LogWarning($"Scene preload failed\n{e}");
}
}
public SceneInstance GetSceneInstance(SceneType sceneType) => _loadedScenes[sceneType];
public async Task PreloadSceneAsync(SceneType sceneType)
{
if (_loadedScenes.ContainsKey(sceneType))
return;
string key = sceneType.ToString();
SceneInstance sceneInstance = await AssetManager.LoadScene(key);
if (sceneInstance.Scene.IsValid())
{
_loadedScenes[sceneType] = sceneInstance;
foreach (var root in sceneInstance.Scene.GetRootGameObjects())
{
root.SetActive(false);
}
}
else
{
Debug.LogError($"[SceneManager] Failed to preload scene: {sceneType}");
}
}
public void ActivateScene(SceneType sceneType)
{
if (_loadedScenes.TryGetValue(sceneType, out var sceneInstance))
{
foreach (var root in sceneInstance.Scene.GetRootGameObjects())
{
root.SetActive(true);
}
UnityEngine.SceneManagement.SceneManager.SetActiveScene(sceneInstance.Scene);
OnSceneChanged?.Invoke(sceneInstance.Scene);
}
else
{
Debug.LogError($"[SceneManager] Scene not loaded: {sceneType}");
}
}
public void DeactivateScene(SceneType sceneType)
{
if (_loadedScenes.TryGetValue(sceneType, out var sceneInstance))
{
foreach (var root in sceneInstance.Scene.GetRootGameObjects())
{
root.SetActive(false);
}
}
}
public async Task UnloadSceneAsync(SceneType sceneType)
{
if (_loadedScenes.TryGetValue(sceneType, out var sceneInstance))
{
await AssetManager.UnloadScene(GetSceneInstance(sceneType));
}
}
}
}