using FirstVillain.Singleton; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Pool; using UnityEngine.ResourceManagement.AsyncOperations; public class AddressableManager : UnitySingleton { private bool _collectionCheck = false; private int _maxPoolSize = 100; private Dictionary> _objectPoolDict = new(); protected override void AwakeSingleton() { base.AwakeSingleton(); Addressables.InitializeAsync(); } public void LoadAssetAsync(string name, Action onComplete) where T : UnityEngine.Object { var handle = Addressables.LoadAssetAsync(name); handle.Completed += handler => { if(handler.Status == UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus.Succeeded) { onComplete(handler.Result); Addressables.Release(handle); } }; } public AsyncOperationHandle LoadTableAssetAsync(string name, Action onComplete) where T : UnityEngine.Object { var handle = Addressables.LoadAssetAsync(name); handle.Completed += handler => { if (handler.Status == UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus.Succeeded) { onComplete(handler.Result); } }; return handle; } //public void InstantiateAsync(string name, Transform parent, Action onComplete) //{ // var handle = Addressables.InstantiateAsync(name, parent); // handle.Completed += handler => // { // onComplete(handle.Result); // Addressables.Release(handle); // }; //} public void Spawn(string name, Transform parent, Action complete) { if(_objectPoolDict.ContainsKey(name)) { var obj = _objectPoolDict[name].Get(); obj.transform.parent = parent; complete(obj); return; } LoadAssetAsync(name, OnComplete => { _objectPoolDict.Add(name, CreateNewObjectPool(OnComplete, name)); var obj = _objectPoolDict[name].Get(); obj.transform.parent = parent; complete(obj); }); } public void Release(GameObject obj) { if (_objectPoolDict.ContainsKey(obj.name)) { try { obj.transform.parent = null; obj.transform.position = Vector3.zero; obj.transform.rotation = Quaternion.identity; 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); } } 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); } }