1.简单介绍

在Unity开发过程中,对象池是一种很好的能用于减少内存开销的方式。在许多场景中,比如角色射击出去的子弹,以及在游戏运行过程中频繁生成的敌人…如果在运行时实时在场景中Instance和Destory,在场景中需要实时生成的GameObject数量比较多的情况下,会增加内存的开销和影响游戏的性能。使用对象池可以很好的对这些需要实时刷新的游戏对象进行管理,在需要时从对象池中取(也就是SetActive(true)),不需要时回收到对象池中(也就是SetActive(false))。

2.思路

以下分了三个类来实现对象池的例子。
1.Pool(对象池类)
其中主要有获取对象GetObject()、回收对象ReleaseObject()、清空对象池ClearPool()三个方法。
2.PoolManager(对象池管理类)
用于管理所有的对象池,方法看代码有详细介绍
3.ObjectPoolTest(测试类)
用于测试对象池

代码实现

1.Pool

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Pool
{int maxCount; //对象池存储数据的最大数据量public string prefabPath; //对象的存储路径List<GameObject> usingList = new List<GameObject>(); //正在使用中的对象List<GameObject> freeList = new List<GameObject>(0); //对象池中空闲的对象public Pool(int count){this.maxCount = count;}/// <summary>/// 从对象池中获取对象/// </summary>/// <returns></returns>public GameObject GetObject(){GameObject obj = null;if(freeList.Count > 0) //如果有空闲列表不为空,从从空闲列表中取对象{obj = freeList[0];usingList.Add(obj); //取出的对象放入正在使用对象列表中freeList.RemoveAt(0); //从空闲列表中移除取出的对象}else //当不存在空闲列表时,则根据资源路径去实例化{if (usingList.Count >= maxCount) //如果当前场景中的对象已经达到对象池的最大上限,直接返回return obj;GameObject prefab = Resources.Load<GameObject>(prefabPath);obj = GameObject.Instantiate(prefab);//将实例化的新对象放入正在使用列表中usingList.Add(obj);int instanceID = obj.GetInstanceID();PoolManager.Instance.instanceIDToPathDic.Add(instanceID, prefabPath); //将克隆出来的对象ID和资源路径存如=入对象池管理类中}return obj;}/// <summary>/// 回收对象/// </summary>/// <param name="obj">需要回收的对象</param>public void ReleaseObject(GameObject obj){usingList.Remove(obj);//将需要回收的对象从正在使用列表中移除freeList.Add(obj); //讲需要回收的对象加入到空闲列表中}/// <summary>/// 清空对象池/// </summary>public void ClearPool(){//销毁使用列表和空闲列表中的对象foreach (var item in usingList)GameObject.Destroy(item);foreach (var item in freeList)GameObject.Destroy(item);//清空列表usingList.Clear();freeList.Clear();}
}

2.PoolManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PoolManager
{static PoolManager instacne; //将对象池管理类设计成单例模式public static PoolManager Instance{get{if (instacne == null)instacne = new PoolManager();return instacne;}}public Dictionary<string, Pool> allPoolDic = new Dictionary<string, Pool>(); //存储了所有对象池public Dictionary<int, string> instanceIDToPathDic = new Dictionary<int, string>(); //存储了所有对象的实例化ID和该对象对应的对象池的资源路径/// <summary>/// 从相应的对象池中取得相应的对象/// </summary>/// <param name="prefabPath"></param>/// <returns></returns>public GameObject GetObjFormPoll(string prefabPath){GameObject obj = null;if(allPoolDic.ContainsKey(prefabPath)) //先判断该资源对应的对象池是否存在{Pool pool = allPoolDic[prefabPath];obj = pool.GetObject();}else{//当前字典中不存在该对象池,则新创建对象池int maxCount = 5;Pool pool = new Pool(maxCount);pool.prefabPath = prefabPath;allPoolDic.Add(prefabPath, pool);obj = pool.GetObject();}//将对象设置成激活状态if (obj != null)obj.SetActive(true);return obj;}/// <summary>/// 将对象还回对象池中/// </summary>public void ReleaseObjToPool(GameObject obj){if (obj == null)return;int instanceID = obj.GetInstanceID();if(instanceIDToPathDic.ContainsKey(instanceID)){string prefabPath = instanceIDToPathDic[instanceID]; //获取该对象对应的资源路径if(allPoolDic.ContainsKey(prefabPath)){Pool pool = allPoolDic[prefabPath];pool.ReleaseObject(obj);obj.SetActive(false); //回收后将对象设置为隐藏状态}}}/// <summary>/// 清空对象池/// </summary>public void ClearAllPool(){foreach (var item in allPoolDic.Values)item.ClearPool(); //清空每个对象池allPoolDic.Clear();instanceIDToPathDic.Clear();}
}

3.ObjectPoolTest

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ObjectPoolTest : MonoBehaviour
{// Update is called once per framevoid Update(){//从对象池中创建对象if(Input.GetKeyDown(KeyCode.Space)){Vector3 pos = new Vector3(Random.Range(-5, 5), Random.Range(-5, 5), Random.Range(-5, 5));GameObject obj = PoolManager.Instance.GetObjFormPoll("Cube");obj.transform.position = pos;}//回收从对象池创建的对象if(Input.GetKeyDown(KeyCode.R)){GameObject obj = GameObject.Find("Cube(Clone)");PoolManager.Instance.ReleaseObjToPool(obj);}}
}

4.测试结果


可以看到,无论我们按几次空格键,场景中最多只会生成5个对象,因为限制了对象池最大数量为5,当你不需要使用时,就按R把对象隐藏起来,而不是直接删除掉。下次需要用到对象的时候直接将状态设置为显示,而不是重新实例化。

Unity对象池简单应用相关推荐

  1. Unity对象池技术

    Unity对象池技术 https://blog.csdn.net/LemonXQ/article/details/77148886 顾名思义,对象池是存放对象的缓冲区.用户可以从缓冲区中放入/取出对象 ...

  2. unity 对象池模式

    1.理解 对象池用于减少内存开销,其原理就是把可能用到到的对象,先存在一个地方(池),要用的时候就调出来,不用就放回去.而不是要用的时候创建,不用的时候销毁. Eg: 我有个飞机,射击子弹,按传统的方 ...

  3. unity对象池(学习)

    对象池:   假设有一个射击游戏,那么场景中必然会创建许多的子弹.如果对于子弹只进行创建子弹-销毁子弹的流程(创建子弹-->销毁),那么可能在1S间创建很多很多的子弹,也会销毁很多子弹,对于游戏 ...

  4. Unity对象的简单平移与旋转

    物体旋转问题,比如说自转,绕转,点击一物体,让其它物体绕该物体转,还有始终面向鼠标或者是player朝向等等,实际上都是一些简单的Rotate\RotateAround\LookAt等的属性,实现起来 ...

  5. Unity程序框架总结归置系列(2)——对象池

    上一篇--Unity程序框架总结归置系列(1)--单例基类 该说的,上一篇也说了.话不多说,直接开肝. unity对象池模块 先直接上源码: using System.Collections.Gene ...

  6. java对象工厂池_[转载]Java对象池技术的原理及其实现

    作者:汪永好 出处:计算机与信息技术 责任编辑: 方舟 [ 2006-11-25 07:00 ] 摘 要 :本文在分析对象池技术基本原理的基础上,给出了对象池技术的两种实现方式.还指出了使用对象池技术 ...

  7. java 对象池 博客_Java对象池技术的原理及其实现的小结

    一起学习 Java对象的生命周期大致包括三个阶段:对象的创建,对象的使用,对象的清除.因此,对象的生命周期长度可用如下的表达式表示:T = T1 T2 T3.其中T1表示对象的创建时间,T2表示对象的 ...

  8. java 对象池 实现_Java对象池技术的原理及其实现

    看到一片有关于java 对象基础知识,故转载一下,同时学习一下. 摘 要 本文在分析对象池技术基本原理的基础上,给出了对象池技术的两种实现方式.还指出了使用对象池技术时所应注意的问题. 关键词 对象池 ...

  9. 9.Unity2D 横版 简单AI 之 敌人跳跃条件优化+自动范围内检测敌人发起攻击(索敌)+对象池优化+主角受伤死亡

    总目录https://blog.csdn.net/qq_54263076/category_11900070.html?spm=1001.2014.3001.5482 1.动画animation和动画 ...

最新文章

  1. python3.9 执行python3.6生成的随机森林模型model.pkl报错,警告版本不一致
  2. 三、Ubuntu16.04 安装Jira8.2.2(自带中文包)和破解
  3. 微信小程序--字体展示
  4. 这么全的数组去重,你怕不怕?
  5. 语音识别:从GMM-HMM到端到端
  6. 【STM32】 keil软件工具--configuration详解(下)
  7. Linux网络/firewalld和netfilter/netfilter/iptables语法
  8. css高清动图,CSS3+PNG实现GIF动画效果
  9. Java描述设计模式(12):外观模式
  10. http协议报文体_http协议详解之响应报文 3
  11. 小程序 自适应rpx
  12. 啊哈 算法 啊哈磊 扫描版pdf
  13. 分享抖音上热门技巧!短视频涨粉+运营攻略!
  14. android svg 线条动画教程,html5 svg制作动态绘制线条动画代码
  15. 前方高能!阿里云双11拼团百团大战已开启!
  16. 关于Flume断点续传(防止重复消费)的解决方案
  17. AtCoder Beginner Contest 164 E Two Currencies Bellman-Ford优化思想+01背包+动归dp状态转移
  18. 惠普暗影精灵8和惠普暗影精灵7区别
  19. 删除word标题前方空格的方法
  20. 6轴机器人运动学(正解)

热门文章

  1. Linux——Shebang符号
  2. 电脑C盘,WINDOWS 里面哪些文件可以删除?
  3. 程序员,事业单位还是计算机老师?
  4. 驱动开发:内核解锁与强删文件
  5. Java IO流详尽解析
  6. 利用ICESat数据提取湖泊的水位高程---以青海湖为例
  7. 使用QQ2013时连接Android物理设备Eclipse发现不了
  8. 怎样买到最便宜的机票
  9. miniconda安装和配置
  10. 串行Flash控制器设计介绍(QSPI)