【Unity】对象池 - 未更新完
自定义泛型对象池
文章目录
- 自定义泛型对象池
- 封装泛型类
- 例子
- 使用Unity自带对象池
封装泛型类
public abstract class MyPool<T> : MonoBehaviour where T :Component
{
[SerializeField] protected T prefab; // 生成的预制体
[SerializeField] protected int defaultNum; // 池子的大小
protected Queue<T> pool = new Queue<T>(); // 队列存储池子
protected bool IsPoolEmpty() => pool.Count == 0;
protected bool IsPoolFull() => pool.Count > prefab;
// 对象池四件套
protected virtual T OnCreateItem() => Instantiate(prefab, transform);
protected virtual void OnGetItem(T obj) => obj.gameObject.SetActive(true);
protected virtual void OnReleaseItem(T obj) => obj.gameObject.SetActive(false);
protected virtual void OnDestroy(T obj) => Destroy(obj.gameObject);
// 用来获得对象后初始化一些信息
protected abstract void InitializedObj(T obj);
protected T Get()
{
T obj;
if (IsPoolEmpty()) obj = OnCreateItem();
else
{
obj = pool.Dequeue();
OnGetItem(obj);
}
InitializedObj(obj);
return obj;
}
protected void Release(T obj)
{
if (IsPoolFull()) OnDestroy(obj);
else
{
pool.Enqueue(obj);
OnReleaseItem(obj);
}
}
}
例子
BoxPool:
public class BoxPool : MyPool<Box>
{
public float IntervalTime = 0.1f;
void Start()
{
StartCoroutine(ContinueCreateBox());
}
// 不断生成对象
private IEnumerator ContinueCreateBox()
{
while (true)
{
Box box = Get(); // 获得出来使用
yield return new WaitForSeconds(IntervalTime);
}
}
// 重写创建对象方法,添加委托
protected override Box OnCreateItem()
{
Box box = base.OnCreateItem();
box.SetBackDestroy(() => {
Release(box);
});
return box;
}
// 完成抽象方法,初始化信息
protected override void InitializedObj(Box obj)
{
obj.transform.position = transform.position + Random.insideUnitSphere * 2f; // 半径2内随机
obj.transform.rotation = Quaternion.identity;
obj.GetComponent<Rigidbody>().velocity = Vector3.zero; // 重置刚体速度,否则会越掉越快
}
}
Box:
public class Box : MonoBehaviour
{
public UnityAction backDestroy;
private float intervalTime = 1.5f;
private float nowTime;
private void Update()
{
nowTime += Time.deltaTime;
if (nowTime > intervalTime)
{
nowTime = 0;
backDestroy?.Invoke();
}
}
public void SetBackDestroy(UnityAction back)
{
backDestroy = back;
}
}