使用字典创建对象池

对象池:池(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);
        }
    }

 

这是一套比较简单的对象池,具备了一些常用的方法,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值