我眼中的unity对象池问题

我眼中的unity对象池问题

   年前再仿一款paper.Io的游戏,2D和3D类型都有,过完年之后试着把其中涉及的一些东西总结记录下。
   废话不多说,先从俩个版本的共同涉及的点开始。

对象池
1,玩过的应该知道,2D也好,3D也好,只要出领地都会不停的生成和销毁轨迹。这样子一方面开销会比较大,另一方面会产生很多内存碎片,程序跑的时间一长,性能就会下降。这个时候,就需要对象池。可以事先创建好一批对象,放在一个集合中,以后每当程序需要新的对象时候,都从对象池里获取,程序用完该对象后,再把该对象归还给对象池。再通俗点,就是你创建的物体会储存在一个容器里,不用的时候把它隐藏起来而不是删除掉,再次创建的时候会访问这个容器如果有的话把它显示出来而不是真的New了一个新的GameObject.

2.下面给出代码

   #region 对象池
    //List对于我的项目来说需要大量多种不同GameObject,因此用List;
    private static Dictionary> ObjectPool = new Dictionary>();

下面我就从一个游戏物体从开始到死亡的顺序讲一下对象池的使用。

 //直接调用静态方法,返回一个需要生成的GameObject;
    public static GameObject CreateObject(string key, GameObject prefab, int x, int y)
    {
        GameObject go = CreateObject(key, prefab);
        Vector3 pos = Map.grids.Grid2WorldPosition(x, y) + Tracker.TopLeftOffset;
        pos.z = -y * 0.02f;
        go.transform.position = pos;
        return go;
    }

现在来看,需要传入一个预制体,至于key只是一个用于标记的字符串名字,可以设置为比如“子弹”。

  
    public static GameObject CreateObject(string key,GameObject prefab)
    {
        GameObject go = PullFromPool(key);
        if (go != null)
        {
            go.SetActive(true);
            return go;
        } 
        go = GameObject.Instantiate(prefab);
        return go;
    }

这一步就是通过这个key来取出对象池里面的游戏物体,设置为激活状态,如果没有就重新生成一个对象。
下面我们来看看从对象池里面进行取的操作。

public static GameObject PullFromPool(string key)
    {
        List list;
        if (ObjectPool.TryGetValue(key,out list) && list.Count > 0)
        {
            GameObject obj = list[0];
             ObjectPool[key].RemoveAt(0); 
             return obj;
        }
        return null;
    }

这一步就是通过key取出一个List表,然后取出第一个对象,这就完成了从对象池中取的操作。
接着我们看看如何储存。

public static void RecycleObject(string key,GameObject obj)
    {
        if (obj == null)
            return;
        obj.SetActive(false);
        PushToPool(key, obj);
    }

把对象设置为未激活状态,同时调用 PushToPool的方法。

 public static void PushToPool(string key, GameObject obj)
    {
        if(ObjectPool.ContainsKey(key))
        {
            ObjectPool[key].Add(obj);
        }
        else
        {
            ObjectPool.Add(key, new List() { obj });
        }
    }

到此,对象池的操作是完成了。如有问题欢迎下方留评论。

你可能感兴趣的:(Unity项目一些总结,unity对象池问题)