对象池,如同线程池,都是为了避免对象的频繁创建销毁
在这里我们使用了上次写的单例来进行开发,因为原则上对象池只需要一个就行了
这里忘记贴出单例
这是上一篇单例的源代码,对象池继承于该对象
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Common
{
/*
* 使用方式:
* 所有频繁创建销毁,都可以通过对象池创建回收
* 创建
* GameObjectPool.Instance.CreateObject(bulletPrefab.name, bulletPrefab, transform.position, transform.rotation);
* 回收
* GameObjectPool.Instance.CollectObject(gameObject);
* 需要通过对象池创建的物体,如需每次执行某一个逻辑,可以实现接口IResetable
*/
public interface IResetable
{
void OnReset();
}
public class GameObjectPool : MonoSingleton <GameObjectPool>
{
private Dictionary<string, List<GameObject>> cache;//对象池保存位置
public override void Init()//初始化
{
base.Init();
cache = new Dictionary<string, List<GameObject>>();
}
public void lala(string asd)//遍历当前key有多少个对象
{
if(cache.ContainsKey(asd))
{
foreach(var i in cache[asd])
{
Debug.Log(i.name);
}
}
//FindUserfulObject(asd);
}
/// <summary>
/// 通过对象池创建对象
/// </summary>
/// <param name="key">类别</param>
/// <param name="prefab">需要创建的实例</param>
/// <param name="Pos">位置</param>
/// <param name="quaternion">旋转</param>
/// <returns>实例</returns>
public GameObject CreateObject(string key,GameObject prefab,Vector3 Pos,Quaternion quaternion)
{
GameObject go = FindUserfulObject(key);//如果你要创建一个物体,你可以先看是否有空对象,没有使用,
if (go == null)
{
// Debug.Log("1");
go = AddObject(key, prefab);//没有就添加进来
}
UserObject(Pos, quaternion, go);//将使用封装成了一个方法,实际上就是,设置transform组件相关信息,以及
return go;
}
//使用对象
private void UserObject(Vector3 Pos, Quaternion quaternion, GameObject go)
{
go.transform.position = Pos;
go.transform.rotation = quaternion;
go.SetActive(true);
//如果不重新执行重制位置,那么就会一直是以前的位置
//go.GetComponent<IResetable>().OnReset();
//这个是重置所有的
foreach(var item in go.GetComponents<IResetable>())
{
item.OnReset();
}
//Debug.Log("go.pos:2 " + go.transform.rotation);
}
//添加对象
private GameObject AddObject(string key, GameObject prefab)
{
GameObject go = Instantiate(prefab);//调用单例去寻找对象,如果没有单例会创建他
if (!cache.ContainsKey(key))//如果不包括的这个键值,那就添加键值,在添加对象
{
cache.Add(key, new List<GameObject>());
}
cache[key].Add(go);
return go;
}
//寻找对象
private GameObject FindUserfulObject(string key)
{
// Debug.Log(4);
if (cache.ContainsKey(key))
{
// Debug.Log(3);
return cache[key].Find(g => g.activeInHierarchy==false);
}
return null;
}
//回收对象
public void CollectObject(GameObject go)
{
go.SetActive(false);
}
/// <summary>
/// 回收对象
/// </summary>
/// <param name="go">对象</param>
/// <param name="delay">时间</param>
public void CollectObject(GameObject go, float delay = 0)
{
//Debug.Log("22222222222+ " + delay);
StartCoroutine(CollectObjectDelay(go, delay));
}
public IEnumerator CollectObjectDelay(GameObject go,float delay)
{
// Debug.Log("111111111111111+ " + delay);
yield return new WaitForSeconds(delay);
go.SetActive(false);
}
//删除对象
public void Clear(string key)
{
foreach (var i in cache[key])
{
Destroy(i);
}
cache.Remove(key);
}
//清空全部
public void ClearAll()
{
foreach(var key in new List<string>(cache.Keys))
{
Clear(key);
}
}
}
}