BITFALL/Assets/BITKit/Unity/Scripts/Utility/Pool.cs

87 lines
2.4 KiB
C#
Raw Normal View History

2023-08-12 01:43:24 +08:00
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Xml.Linq;
using UnityEngine;
using UnityEngine.Pool;
using Object = UnityEngine.Object;
namespace BITKit
{
[System.Serializable]
public class UnityPool<T> where T : Component
{
public UnityPool()
{
pool = new ObjectPool<T>(Spawn, OnGet, OnReturn, OnDestroy, maxSize: 16);
}
2023-10-29 15:27:13 +08:00
[Header(Constant.Header.Settings)]
[SerializeField] private int defaultCapacity = 16;
2023-08-12 01:43:24 +08:00
[Header(Constant.Header.Prefabs)]
2023-10-29 15:27:13 +08:00
[SerializeField] private T prefab;
2023-08-12 01:43:24 +08:00
[Header(Constant.Header.Gameobjects)]
2023-10-29 15:27:13 +08:00
[SerializeField] private Transform root;
2023-08-12 01:43:24 +08:00
private ObjectPool<T> pool;
2023-10-29 15:27:13 +08:00
private readonly List<T> _list=new();
2023-11-15 23:54:54 +08:00
public int DefaultCapacity
{
get => defaultCapacity;
set => defaultCapacity = value;
}
2023-10-29 15:27:13 +08:00
2023-08-12 01:43:24 +08:00
public T Get(T element = null, Transform _root = null)
{
2023-10-29 15:27:13 +08:00
if (_list.Count == defaultCapacity)
{
2023-11-15 23:54:54 +08:00
var next = _list[0];
next.gameObject.SetActive(false);
_list.RemoveAt(0);
_list.Add(next);
next.gameObject.SetActive(true);
return next;
2023-10-29 15:27:13 +08:00
}
2023-08-12 01:43:24 +08:00
if (element is not null)
prefab = element;
if (_root is not null)
root = _root;
2023-10-29 15:27:13 +08:00
var instance = pool.Get();
_list.Add(instance);
return instance;
}
public void Return(T element)
{
pool.Release(element);
_list.Remove(element);
2023-08-12 01:43:24 +08:00
}
private T Spawn() => Object.Instantiate(prefab, root);
private void OnGet(T element) => element.gameObject.SetActive(true);
private void OnReturn(T element) => element.gameObject.SetActive(false);
private void OnDestroy(T element) => Object.Destroy(element.gameObject);
#region
private readonly ConcurrentDictionary<string, T> _dictionary=new();
public T GetByKey(string key)
{
var instance = _dictionary.GetOrAdd(key, s => Get());
return instance;
}
public void RemoveByKey(string key)
{
_dictionary.TryRemove(key);
}
#endregion
}
}