对象池ObjectPool的简单实现

Posted linawz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对象池ObjectPool的简单实现相关的知识,希望对你有一定的参考价值。

我对对象池的简单理解:当一个游戏需要产生大量游戏物体又需要频繁销毁时,可用一个对象池将游戏物体存储起来。目的是优化内存。

以下两篇我参考过觉得OK的博文:

https://blog.csdn.net/u013236878/article/details/52443066

https://www.jianshu.com/p/6133fb7e0819

unity内简单实现一下:

1.canvas下新建空物体命名为07_ObjectPool,新建一个cube

技术图片

 

 2.创建一个脚本,内容如下,挂载在空物体上。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 对象池
/// </summary>
public class ObjectPool : MonoBehaviour {

    //获取资源
    public GameObject monster;
    //怪物对象池
    private Stack<GameObject> monsterPool;
    //当前游戏世界里存在的或者说已经激活的怪物对象
    private Stack<GameObject> activeMonsterList;

	// Use this for initialization
	void Start () {
        monsterPool = new Stack<GameObject>();
        activeMonsterList = new Stack<GameObject>();
	}
	
	// Update is called once per frame
	void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            //如果我们需要游戏物体时我们要从池的管理内取
            GameObject itemGo = GetMonster();
            //做后续工作
            itemGo.transform.position = Vector3.one;
            activeMonsterList.Push(itemGo);
        }else if (Input.GetMouseButtonDown(1))
        {
            if (activeMonsterList.Count > 0)
            {
                if (activeMonsterList.Count > 0)
                {
                    //如果我们不适用或者销毁了当前怪物对象
                    //那么我们需要直接把怪物对象扔进池子
                    PushMonster(activeMonsterList.Pop());
                }
            }
        }
	}

    private GameObject GetMonster()
    {
        GameObject monsterGo = null;
        if (monsterPool.Count<=0)       //如果池子里没有怪物对象
        {
            monsterGo = Instantiate(monster);
        }
        else                            //池子有怪物对象
        {
            monsterGo = monsterPool.Pop();
            monsterGo.SetActive(true);
        }
        return monsterGo;
    }

    private void PushMonster(GameObject monsterGo)
    {
        monsterGo.transform.SetParent(transform);
        monsterGo.SetActive(false);     //令不使用的游戏对象失活
        monsterPool.Push(monsterGo);
    }
}

  

3.把创建的cube赋给monster对象,鼠标左键创建,右键销毁。可见右键销毁时并没有真正把物体销毁掉,而只是隐藏了起来,等到下一次左键创建新物体时再把隐藏的物体现实出来,这样就达到了节约内存的效果。只有当隐藏的对象全部都显示完毕但仍然在进行创建操作时,才会真正实例化一个物体。

技术图片

 

 

末尾补充:对象池只需要一个,为此对象池应该被设计应用到一个安全的模式,所以要采用单例模式。我对单例模式的理解:类似于当前CPU只能运行一个进程,在运行这个的时候其他进程就不能抢占资源,补充一篇博文,里面讲解较为详细。(里面的模式代码粗略看了一下有点PV操作问题的感觉。。)

https://blog.csdn.net/jason0539/article/details/23297037

 

先发了有坑后面填

以上是关于对象池ObjectPool的简单实现的主要内容,如果未能解决你的问题,请参考以下文章

JS模式--通用对象池的实现

Unity对象池试水

ObjectPool 对象重用

brpc源码学习- 内存池ObjectPool

brpc源码学习- 内存池ObjectPool

brpc源码学习- 内存池ObjectPool