using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; #if UNITY_EDITOR using UnityEditor.AddressableAssets; #endif using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.SceneManagement; namespace DDD { public class AssetManager : Singleton, IManager { private static readonly Dictionary _cachedHandles = new(); protected override void OnApplicationQuit() { base.OnApplicationQuit(); ReleaseAllCached(); } public void PreInit() { } public async Task Init() { await Addressables.InitializeAsync().Task; } public void PostInit() { } public static async Task LoadAsset(string key) where T : UnityEngine.Object { if (_cachedHandles.TryGetValue(key, out var handle)) { if (handle.IsValid() && handle.Result is T result) return result; Debug.LogWarning($"[AssetManager] Type mismatch or invalid handle for key: {key}"); return handle.Result as T; } // ✅ 새로 로드 var newHandle = Addressables.LoadAssetAsync(key); await newHandle.Task; if (newHandle.Status == AsyncOperationStatus.Succeeded) { _cachedHandles[key] = newHandle; return newHandle.Result; } Debug.LogError($"[AssetManager] Failed to load asset: {key}"); return null; } public static async Task> LoadAssetsByLabel(string label) where T : UnityEngine.Object { var handle = Addressables.LoadAssetsAsync(label, null); await handle.Task; if (handle.Status == AsyncOperationStatus.Succeeded) return handle.Result.ToList(); Debug.LogError($"[AssetManager] Failed to load assets with label: {label}"); return new List(); } public static async Task LoadScene(AssetReference assetReference, LoadSceneMode mode = LoadSceneMode.Additive) { var handle = Addressables.LoadSceneAsync(assetReference, mode); await handle.Task; if (handle.Status == AsyncOperationStatus.Succeeded) return handle.Result; Debug.LogError($"Scene load failed: {assetReference}"); return default; } public static async Task UnloadScene(SceneInstance sceneInstance) { var handle = Addressables.UnloadSceneAsync(sceneInstance); await handle.Task; } public static void ReleaseAllCached() { if (_cachedHandles.Count == 0) return; foreach (var kvp in _cachedHandles) { var handle = kvp.Value; if (handle.IsValid()) { Addressables.Release(handle); //Debug.Log($"[AssetManager] Released handle for key: {kvp.Key}"); } } _cachedHandles.Clear(); Debug.Log("[AssetManager] 모든 캐시된 Addressable 리소스를 해제했습니다."); } public static bool HasLabel(string addressKey, string label) { #if UNITY_EDITOR var settings = AddressableAssetSettingsDefaultObject.Settings; if (settings == null) return false; var entry = settings.groups .SelectMany(g => g.entries) .FirstOrDefault(e => e.address == addressKey); if (entry == null) return false; return entry.labels.Contains(label); #else return true; #endif } } }