using FirstVillain.Singleton; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.Pool; using UnityEngine.ResourceManagement.AsyncOperations; public class AddressableManager : UnitySingleton { [SerializeField] private Transform _objectPoolRoot; private bool _collectionCheck = false; private int _maxPoolSize = 100; private Dictionary> _objectPoolDict = new(); protected override void AwakeSingleton() { base.AwakeSingleton(); Addressables.InitializeAsync(); } public T LoadAssetAsync(string name) where T : UnityEngine.Object { var handle = Addressables.LoadAssetAsync(name); var result = handle.WaitForCompletion(); Addressables.Release(handle); return result; } public GameObject Spawn(string name, Transform parent) { if(!_objectPoolDict.ContainsKey(name)) { var loaded = LoadAssetAsync(name); _objectPoolDict.Add(name, CreateNewObjectPool(loaded, name)); } GameObject obj; obj = _objectPoolDict[name].Get(); obj.transform.SetParent(parent); return obj; } public void Release(GameObject obj) { if (_objectPoolDict.ContainsKey(obj.name)) { try { obj.transform.parent = null; try { _objectPoolDict[obj.name].Release(obj); } catch { obj.SetActive(false); } } catch (Exception ex) { Debug.LogError($"Exception has occured!!! Object : {obj.name} === {ex.Message}"); } } else { Debug.LogWarning($"Object[{obj.name}] does not exist in pool dictionary. But it's been destroyed anyway :D"); Destroy(obj); } } public void ReleaseAll() { foreach (var pool in _objectPoolDict) { pool.Value.Dispose(); } _objectPoolDict.Clear(); } private ObjectPool CreateNewObjectPool(GameObject prefab, string resourceName) { return new ObjectPool( () => { GameObject obj = Instantiate(prefab); obj.name = resourceName; return obj; }, OnGetFromPoolActive, OnReleasedToPool, OnDestroyPoolObject, _collectionCheck /* Collection checks will throw errors if we try to release an item that is already in the pool.*/, 10/*defalut capacity*/, _maxPoolSize ); } private void OnGetFromPoolInActive(GameObject obj) { obj.SetActive(false); } private void OnGetFromPoolActive(GameObject obj) { obj.SetActive(true); } private void OnReleasedToPool(GameObject obj) { obj.SetActive(false); } private void OnDestroyPoolObject(GameObject obj) { Destroy(obj); } }