对象池:池(Pool),与集合仔某种意义上有些相似。水池,是一定数量的水的集合,内存池,是一定数量的已经分配好的内存的集合,线程池,是一定数量的已经创建好的线程的集合,那么对象池,就是一定数量的已经创建好的对象的集合,
1. 对象池服务可以减少从头创建每个对象的系统开销,
2. 在需要对象时,直接从池中提取,停用时放回池中,等待下一次请求
3. 对象池可以控制所使用对象的数量
在做游戏时,经常有同一个预制体(Prefab)需要多次用到,需要反复使用(Instantiate)创建对象,这种方法比较好资源,如果对象大量使用,会造成游戏卡顿,卡死等现象,
使用对象池可以减少这种消耗,通俗的将就是**用时间换空间**使用**SetActive(true/false)**来控制对象的创建和删除,
说了那么多就不废话了 直接上代码
单例模式,
/// <summary>
/// 泛型单例
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class MonoSingleton<T> : MonoBehaviour where T :MonoSingleton<T>
{
protected static T _Instance = null;
public static T Instance
{
get
{
if (_Instance ==null )
{
_Instance = FindObjectOfType<T>();
}
return _Instance;
}
}
}
使用字典创建对象池
Dictionary<string, List<GameObject>> cache; //对象池
void Start()
{
cache= new Dictionary<string, List<GameObject>>();//实例化
}
创建对象的函数
/// <summary>
/// 创建对象
/// </summary>
/// <param name="go"></param>
/// <param name="pos"></param>
/// <param name="quaternion"></param>
/// <returns></returns>
public GameObject CreateObject(GameObject go,Vector3 pos,Quaternion quaternion )
{
//判断池中是否有物体
GameObject temp = FindUsable(go.name);
//如果对象池中有对象
if (temp != null)
{
temp.transform.localPosition = pos; //位置
temp.transform.rotation = quaternion; //旋转
temp.SetActive(true); //显示对象
}
else
{
temp = Instantiate(go, pos, quaternion);//创建对象
temp.name = go.name;
Add(temp.name, temp );//添加到字典中
}
return temp;
}
查找对象是否可以被使用 池中是否存在对象
/// <summary>
/// 查找对象是否可以被使用
/// </summary>
/// <returns></returns>
public GameObject FindUsable(string key)
{
if (cache .ContainsKey (key))
{
//查找对象池中是否有隐藏的物体
GameObject temp = cache[key].Find(go => !go.activeSelf);
return temp;
}
return null;
}
把对象添加到池中的方法
/// <summary>
/// 把物体添加到池中
/// </summary>
/// <param name="key"></param>
/// <param name="go"></param>
public void Add(string key,GameObject go)
{
//当前字典有没有这个键
if (!cache.ContainsKey(key))
{
cache.Add(key, new List<GameObject>());
}
//给这个键 添加对象
cache[key].Add(go);
}
回收对象的方法 (把不用的对象放回到池中)
/// <summary>
/// 即时收回对象
/// </summary>
public void CollectObject(GameObject go)
{
if (go!= null)
{
go.SetActive(false);
}
}
/// <summary>
/// 延迟收回对象
/// </summary>
/// <param name="go">对象</param>
/// <param name="delay">延迟时间</param>
public void CollectObject(GameObject go,float delay)
{
StartCoroutine(DelayCollect(go, delay));
}
IEnumerator DelayCollect( GameObject go,float delay)
{
yield return new WaitForSeconds(delay);
CollectObject(go );
}
释放对象(删除对象)
/// <summary>
/// 释放一个资源
/// </summary>
public void Clear(string key)
{
for (int i = 0; i < cache[key].Count; i++)
{
Destroy(cache[key][i]);
}
cache.Remove(key);
}
/// <summary>
/// 释放全部资源
/// </summary>
public void ClaerAll()
{
foreach (var item in cache.Keys )
{
for (int i = 0; i < cache[item].Count; i++)
{
Destroy(cache[item][i]);
}
}
cache.Clear();
}
最后一步 调用
public GameObject go;
public GameObject En;
void Update()
{
if (Input.GetMouseButtonDown (0))
{
GameObject game = GameObjectPoon.Instance.CreateObject(go,Vector3 .zero ,Quaternion .identity );
GameObjectPoon.Instance.CollectObject(game,3f);
}
}
这是一套比较简单的对象池,具备了一些常用的方法,