美文网首页
简单的对象池实例

简单的对象池实例

作者: 深吸一口气 | 来源:发表于2022-02-27 22:45 被阅读0次
using System.Collections.Generic;
using UnityEngine;

public class SimplePool : MonoBehavior
{
    // 物体的池子,用字典表示。键为种类 ID,值是同类物体的队列
    // 以预制体的 ID 作为每个种类的标识 ID
    private Dictionary<int, Queue<GameObject>> m_Pool = new Dictionary<int, Queue<GameObject>>{};

    // 记录所有离开对象池的物体。键是物体引用,值是种类 ID
    // 离开对象池的物体会从 m_Pool 中离开,但是要记录在 m_OutObjs 字典里
    private Dictionary<GameObject, int> m_OutObjs = new Dictionary<GameObject, int>{};

    // 创建物体,预制体由调用者自备
    public GameObject Create(GameObject prefab)
    {
        // 以预制体的物体 ID,作为该类型物体的 ID
        int id = prefab.GetInstanceID();
        // 尝试从对象池中获取这个物体
        GameObject go = _GetFromPool(id);
        if(go == null)
        {
            // 取不到物体,就根据预制体创建物体
            go = Instantiate<GameObject>(prefab);
            // 如果初次遇到这类物体,需要添加一个新的类型
            if(!m_Pool.ContainsKey(id))
            {
                m_Pool.Add(id, new Queue<GameObject>());
            }
        }

        // 标记新创建的物体离开了对象池
        m_OutObjs.Add(go, id);
        return go;
    }

    // 销毁(回收)物体
    public void Destroy(GameObject go)
    {
        // 判断物体是不是由对象池创建
        if(!m_OutObjs.ContainsKey(go))
        {
            Debug.LogWarning("回收的物体并不是对象池创建的!" + go);
            return;
        }

        // 该物体属于哪个种类
        int id = m_OutObjs[go];

        go.transform.parent = transform;
        go.SetActive(false);

        // 加入队列,并且去掉离开的标记
        m_Pool[id].Enqueue(go);
        m_OutObjs.Remove(go);
    }

    // 从对象池中根据类型 ID 取出物体。如果类型不存在或者物体暂时用完了,返回 null
    private GameObject _GetFromPool(int id)
    {
        if(!m_Pool.ContainsKey(id) || m_Pool[id].Count == 0)
        {
            return null;
        }
        GameObject obj = m_Pool[id].Dequeue();
        obj.SetActive(true);
        return obj;
    }
}

相关文章

  • 简单的对象池实例

  • Netty Recycler源码解读

    Recycler是一个轻量级的对象缓存池,用来实现对象的复用。下面是使用Recycler的一个简单实例: Recy...

  • 简单的对象池

    对象池的实现: 一、先定义个List集合用来存储对象,起初先在池子里放置一定数量的对象,并且把他设置为false;...

  • 【设计模式】之对象池模式--JDBC连接池实现案例

    对象池设计模式 对象池设计模式的目标 对象池可以显著提高性能,在那些初始化一个类实例的代价比较高、但是使用频率比较...

  • 【结构型模式十二】享元模式-2(Flyweight)

    3.3 对享元对象的管理## 虽然享元模式对于共享的享元对象实例的管理要求,没有实例池对实例管理的要求那么高,但是...

  • js函数对象和回调

    函数对象和实例对象 函数对象:将函数作为对象使用时,简称函数对象实例对象:new函数产生的对象,简单对象 ()的左...

  • Unity--简单的对象池

    简单的对象池分三步走: 建立对象池 拿到对象 回收对象 Test为对象池,Obj为自动回收的物体 Test.cs ...

  • java基础面试

    1、请解释。string类两种对象实例化的区别 *直接赋值:只会产生一个实例化对象,并且可以自动保存到对象池之中。...

  • 自动释放池工作原理

    自动释放池是NSAutorelease类的一个实例,当向一个对象发送autorelease消息时,该对象会自动入池...

  • Unity3d中的细节优化 第一篇

    1.Instantiate实例化操作技巧。 将频繁需要实例化,销毁的对象放入缓存池,可以大量减少实例化,销毁的开销...

网友评论

      本文标题:简单的对象池实例

      本文链接:https://www.haomeiwen.com/subject/hzrkrrtx.html