99 lines
2.8 KiB
C#
99 lines
2.8 KiB
C#
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.Events;
|
||
public class CommonPool<T> where T : Component
|
||
{
|
||
public readonly Transform poolRoot;
|
||
public readonly T prefab;
|
||
public readonly UnityAction<T> createAction;
|
||
private readonly Queue<T> _pool;
|
||
private bool _kill;
|
||
|
||
public CommonPool(Transform poolRoot, T prefab, UnityAction<T> createAction = null)
|
||
{
|
||
this.poolRoot = poolRoot;
|
||
this.prefab = prefab;
|
||
this.createAction = createAction;
|
||
_pool = new Queue<T>();
|
||
}
|
||
|
||
// 回收
|
||
public void PushItem(T item)
|
||
{
|
||
if (!_kill)
|
||
{
|
||
item.gameObject.SetActive(false);
|
||
item.transform.SetParent(poolRoot, false);
|
||
if (prefab != null)
|
||
item.transform.localScale = prefab.transform.localScale;
|
||
// 恢复缩放数值,防止缩放被其他组件修改
|
||
_pool.Enqueue(item);
|
||
OnPushItem(item);
|
||
}
|
||
}
|
||
|
||
// 获取
|
||
public T PullItem(Transform parent)
|
||
{
|
||
return PullItem(parent, Quaternion.identity, Vector3.one);
|
||
}
|
||
|
||
public T PullItem(Transform parent, Quaternion rotation, Vector3 scale)
|
||
{
|
||
T item = null;
|
||
if (!_kill)
|
||
{
|
||
if (_pool.Count > 0)
|
||
{
|
||
item = _pool.Dequeue();
|
||
item.transform.SetParent(parent, false);
|
||
}
|
||
else
|
||
item = CreateItem(parent);
|
||
// 注:Prefab现在修改为不激活状态了
|
||
item.gameObject.SetActive(true);
|
||
item.transform.rotation = rotation;
|
||
item.transform.localScale = scale;
|
||
OnPullItem(item);
|
||
}
|
||
|
||
return item;
|
||
}
|
||
|
||
public T CreateItem(Transform parent)
|
||
{
|
||
var item = Object.Instantiate(prefab, parent, false);
|
||
item.gameObject.TrimCloneInName();
|
||
GCGame.Utils.ResetShader(item.gameObject);
|
||
if (createAction != null)
|
||
createAction(item);
|
||
return item;
|
||
}
|
||
|
||
public virtual void Kill(bool destroyCache = false)
|
||
{
|
||
_kill = true;
|
||
// 注:特殊处理,Prefab在当前项目是为激活的实例化物体,而不是传统Prefab
|
||
// if (prefab != null)
|
||
// Object.Destroy(prefab.gameObject);
|
||
// 注:实例物体随池根节点或者场景切换摧毁,不需要主动摧毁
|
||
// 不切换场景析构时,需要同时析构缓存物体
|
||
if (destroyCache)
|
||
{
|
||
while (_pool.Count > 0)
|
||
{
|
||
var item = _pool.Dequeue();
|
||
if (item != null)
|
||
Object.Destroy(item.gameObject);
|
||
}
|
||
}
|
||
}
|
||
|
||
protected virtual void OnPullItem(T item)
|
||
{
|
||
}
|
||
|
||
protected virtual void OnPushItem(T item)
|
||
{
|
||
}
|
||
} |