对象池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的简单实现的主要内容,如果未能解决你的问题,请参考以下文章