Unity 对象池的使用

  在游戏开发过程中,我们经常会遇到游戏发布后,测试时玩着玩着明显的感觉到有卡顿现象。出现这种现象的有两个原因:一是游戏优化的不够好或者游戏逻辑本身设计的就有问题,二是手机硬件不行。好吧,对于作为程序员的我们只能从第一个原因着手了,那就开始对着Profiler看性能开销,接下来就开始做各种内存,特效,代码上的优化了。对于这种问题,有经验的开发者在一开始就会做一个规范的设计,就我们的项目而言,设计时包含了角色池,怪物池,特效池,经验池,伤害池......所谓的对象池就是尽可能的复用内存中已经驻留的资源来减少频繁的IO耗时操作。使用对象池可以很好的解决内存上的压力,但是我们自己要维护好池中对象的状态。就粒子特效而言,当粒子特效释放后我们要对它Reset到初始状态,这样才能保证每次释放出的特效播放是正常的。好了,废话不多说了,开始一个简单的小例子,就拿我在项目中做的伤害和经验飘字为例。说到这个伤害和经验飘字,尤其是在MMO或者ARPG游戏中太常见了,进入自动战斗后,服务器会频繁的告诉客户端打怪耗了多少血获得了多少经验所以客户端要做的表现是很频繁的。我们不可能根据收到服务器的消息立刻去实例和销毁对应的飘字吧?这样还有一个问题,由于网络消息太快了,客户端不做处理的话一坨就叠加到一块了,,,我们自己都看不先去何况玩家呢?对于这个处理上,我选择使用一个队列,将服务器下发的消息分类入队,开一个协程去处理队列的信息同时控制好处理间隔时间,实例化的飘字预制放到经验池中,复用池中空闲的对象。简单的经验池,开始撸代码。

1,建一个简单的界面

2,我们先创建一个对象池

创建简单吧,接下来取到这个池的对象。

ExpPool = PoolManager.Pools["ExpPool"];

向池子中添加我们要复用的对象,例如粒子,模型,音频,,,等等。怎么添加呢?

ExpPool = PoolManager.Pools["ExpPool"];//获取对象池
if (!ExpPool._perPrefabPoolOptions.Contains(prefabPool))
{
	prefabPool = new PrefabPool(Resources.Load<Transform>("LabExp"));//加载本地预制
	//默认初始化一个Prefab
	prefabPool.preloadAmount = 1;
	//开启限制
	prefabPool.limitInstances = true;
	//关闭无限取Prefab
	prefabPool.limitFIFO = false;
	//限制池子里最大的Prefab数量
	prefabPool.limitAmount = 10;
	//开启自动清理池子
	prefabPool.cullDespawned = true;
	//最终保留
	prefabPool.cullAbove = 10;
	//多久清理一次
	prefabPool.cullDelay = 5;
	//每次清理几个
	prefabPool.cullMaxPerPass = 5;
	//初始化内存池
	ExpPool._perPrefabPoolOptions.Add(prefabPool);//添加到池中
	ExpPool.CreatePrefabPool(ExpPool._perPrefabPoolOptions[ExpPool.Count]);
}
else
{
	Debug.Log("Already in prefabPool!");
}

3,添加完成了,那么接下来该去对象池中取对象了。

Transform labExp = ExpPool.Spawn("LabExp");

此处LabExp是加入到对象池的对象名称,也就是我本地经验飘字预制的名称。

4,最后一步对象状态初始化。

IEnumerator ResetPrefab(Transform obj)
{
	yield return new WaitForSeconds(2f);
	obj.GetComponent<TweenPosition>().ResetToBeginning();
	obj.GetComponent<TweenScale>().ResetToBeginning();
	obj.GetComponent<TweenAlpha>().ResetToBeginning();
	ExpPool.Despawn(obj);
}

将使用过后的对象还原到开始状态,好了,一个简单的对象池可以使用了!

对了还有重要的一步:记得给对象池的父节点加上一个Panel,这样不会影响的其他界面组建的重绘。

PS:如果本文写的有不正确的地方记得@我,共同学习!

工程地址:https://github.com/wuzhangwuzhang/ExpPoolManager.git

时间: 08-04

Unity 对象池的使用的相关文章

屏幕坐标和世界坐标的转换+对象池技术(3D打地鼠小游戏)

游戏中可能经常会遇到需要某个物体跟着鼠标移动,然后又需要把物体放在某个鼠标指定的位置 实现方式 Camera.main.WorldToScreenPoint Camera.main.ScreenToWorldPoint 3D打地鼠实例 我这里用到的素材都比较简陋,几乎全是用Unity做的 首先是锤子 就是两个Cylinder,在把手的位置放一个空物体用于模拟锤子的动作,命名为Hammer,把锤子作为Hammer的子物体,给Hammer添加Animation动画: 在三个关键帧位置设置Hammer

Unity3D中对象池的实现

在Unity中常常会遇到需要重复创建,销毁某些物体的情况,比如fps类游戏中的子弹,rpg类游戏中的小怪等等,如果直接使用Instantiate和Destroy的话,会浪费系统的资源,而使用对象池则能够节省下这些浪费. 这里使用一个重复利用子弹的进行发射的简单场景来演示对象池. 首先需要一个在场景中创建一个Cube,充当子弹. 然后在Assets目录下创建Resources文件夹,在Cube上添加上刚体,取消重力后,将Cube拖入Resources文件夹内作为一个预设,在场景中删除这个Cube.

[译]Unity3D内存管理——对象池(Object Pool)

从一个简单的对象池类开始说起 对象池背后的理念其实是非常简单的.我们将对象存储在一个池子中,当需要时在再次使用,而不是每次都实例化一个新的对象.池的最重要的特性,也就是对象池设计模式的本质是允许我们获取一个“新的”对象而不管它真的是一个新的对象还是循环使用的对象.该模式可以用以下简单的几行代码实现: public class ObjectPool<T> where T : class, new() { private Stack<T> m_objectStack = new Sta

整数对象池

Python 的内建对象存放在源代码的Objects目录下.intobject.c用于整数对象 在 Python 中,整数分为小整数对象和大整数对象 小整数对象 由于数值较小的整数对象在内存中会很频繁地使用,如果每次都向内存申请空间.请求释放,会严重影响 Python 的性能.好在 整数对象 属于不可变对象,可以被共享而不会被修改导致问题,所以为 小整数对象 划定一个范围,即小整数对象池,在Python运行时初始化并创建范围内的所有整数,这个范围内的 整数对象是被共享的,即一次创建,多次共享引用

对象池实现分析

对象池实现分析 什么是对象池技术?对象池应用在哪些地方? 对象池其实就是缓存一些对象从而避免大量创建同一个类型的对象,类似线程池的概念.对象池缓存了一些已经创建好的对象,避免需要时才创建对象,同时限制了实例的个数.池化技术最终要的就是重复的使用池内已经创建的对象.从上面的内容就可以看出对象池适用于以下几个场景: 创建对象的开销大 会创建大量的实例 限制一些资源的使用 如果创建一个对象的开销特别大,那么提前创建一些可以使用的并且缓存起来(池化技术就是重复使用对象,提前创建并缓存起来重复使用就是池化

c++实现游戏开发中常用的对象池(含源码)

c++实现游戏开发中常用的对象池(含源码) little_stupid_child2017-01-06上传 对象池的五要素: 1.对象集合 2.未使用对象索引集合 3.已使用对象索引集合 4.当前使用量 5.最大使用量 http://download.csdn.net/download/little_stupid_child/9730912

对象池的实现与性能测试

引用对象池的好处:从池中操作对象比直接new.free要性能更快,且能避免内存碎片的堆积 先贴对象池的代码: namespace LegendServer.Util { //对象基 public abstract class ObjectBase { public abstract void Init(); } //对象池管理器(采用堆栈存储,支持动态扩容,支持多线程,新扩容的则自动加入到池中能被重复利用) public class ObjectPoolManager<T> where T :

深度剖析C++对象池自动回收技术实现

http://www.tuicool.com/articles/mQBfQfN 对象池可以显著提高性能,如果一个对象的创建非常耗时或非常昂贵,频繁去创建的话会非常低效.对象池通过对象复用的方式来避免重复创建对象,它会事先创建一定数量的对象放到池中,当用户需要创建对象的时候,直接从对象池中获取即可,用完对象之后再放回到对象池中,以便复用.这种方式避免了重复创建耗时或耗资源的大对象,大幅提高了程序性能.本文将探讨对象池的技术特性以及源码实现. 对象池类图 ObjectPool:管理对象实例的pool

对象池的设计

对象池的设计及其实现 对象池概述: 对象池模型创建并拥有固定数量的对象,当程序需要一个新的对象时,如果对象池中有空闲对象,则立即返回,否则才创建新的该类对象.当一个对象不再被使用时,其应该应该将其放回对象池,以便后来的程序使用.由于系统资源有限,一个对象池模型应该指定其可容纳的最大对象数量.当达到该数量时,如果仍然有对象创建请求,则抛出异常或者阻塞当前调用线程,直到一个对象被放回对象池中. 对象池模型适用的场景: (1)需要使用大量对象 (2)这些对象的实例化开销比较大且生存期比较短 对象池优势