孙广东 2014.6.28

非常早之前看到的外国文章,认为不错,分享一下。 对象池在AssetStore中也是有非常多插件的,可是有些重了。自己写一个轻量的岂不是非常好。

当你须要创建大量某种类型对象时,它能够方便地又一次使用单个对象,而不是不断地 创建/销毁(操作会导致大量的垃圾回收)。此ObjectPool脚本,生成和回收您的游戏对象的对象池。
代码:https://github.com/UnityPatterns/ObjectPool
http://unitypatterns.com/resource/objectpool/

特性:
?选择性地池对象基于prefab类型
?简单和表达式语法 对于 实例化和回收
?轻松地预先实例化对象,以防止执行时实例化
?搜索和跟踪全部生成/池子内的在场景中实例化的

怎么使用?
通常情况下,当您实例化并销毁prefabs的实例,您在执行时不断创建新的对象和摧毁它们。这可能会导致执行时垃圾回收和偶尔的帧速率下降。

ObjectPool 能够防止这样的。通过预先实例化。而不是被摧毁然后又一次生成对象!

生成池子中的对象:
比如,假设我有能发射子弹对象的炮塔。我能创建 10 枚一模一样的子弹对象并又一次使用。子弹将永远不会被销毁。仅仅是取消激活、须要生成时又一次激活他们。
ObjectPool要做到这一点,你仅仅要调用CreatePool() 生成指定Prefab的对象。

public class Turret : MonoBehaviour
{
public Bullet bulletPrefab;
void Start()
{
//Create a pool with 10 pre-instantiated bullets in it
bulletPrefab.CreatePool(10);
//Or you could also pre-instantiate none, and the system will instantiate them as it needs them
bulletPrefab.CreatePool();
}
}

如今你能够使用ObjectPool类中的Spawn() and Recycle() 来取代Instantiate() and Destroy()方法。比如。当抢发射子弹时。我生成子弹实例:

public class Turret : MonoBehaviour
{
public Bullet bulletPrefab;
public void ShootBullet()
{
//Spawn a bullet at my position with my rotation
bulletPrefab.Spawn(transform.position, transform.rotation);
}
}

当你想要回收这个实例,在你想要消失的组件或者对象上调用Recycle()函数。

当子弹发生碰撞时,我们将回收它。

public class Bullet : MonoBehaviour
{
void OnCollisionEnter(Collider other)
{
//De-activate the object and return it to the spawn pool
gameObject.Recycle();
//You can also use this:
//this.Recycle();
}
}

函数Spawn()被创建的对象的引用, 所以你能够存储这个对象或者调用它的其它方法. 这个函数不像Unity的 Instantiate(), 你不须要强制类型转换得到 GameObject or Component.

小心用回收的对象!
如今,您的对象正在被回收和又一次使用,你必须要小心,由于假设您的实例有不论什么变量被改变。您必须手动重置它们。你能够通过使用Unity提供的的 OnEnable() 和 OnDisable() 函数,仅仅要您的实例使用spawned or recycled函数将会触发OnEnable() 和 OnDisable()。

比如。这是不对的:

public class Bullet : MonoBehaviour
{
public float travelDuration;
float timer = 0; //Only gets set to zero once!
void Update()
{
timer += Time.deltaTime;
if (timer >= travelDuration)
{
gameObject.Recycle();
}
}
}

为什么不对呢?

由于我们的timer变量计数。但永远不会返回到零!所以当回收并在此使用时,它已经不是最開始的状态了。

我们能够非常easy解决问题:

public class Bullet : MonoBehaviour
{
public float travelDuration;
float timer;
void OnEnable()
{
//Correct! Now timer resets every single time:
timer = 0;
}
void Update()
{
timer += Time.deltaTime;
if (timer >= travelDuration)
{
gameObject.Recycle();
}
}
}

如今我们的子弹正确重置他的timer变量。

你能通过对象引用预制体,在曾经是不能的
GameObject如今有组件的扩展方法

InitialPoolSize 參数已加入到 CreatePool()函数总,并告诉它要预先实例化多少的对象,这些都是最初被隐藏和延迟生成的。
您还能够将 ObjectPool 附加到一个游戏对象,通过inspector 设置要 预先实例化 的预制体
附加函数已经加入了用于搜索/统计 实例对象

假设你想要 RecycleAll 要使用派生类型,然后更改这:
var active = instance.prefabLookup.Keys.Where(p => p.GetType() == typeof(T).ToList();
to:
var active = instance.prefabLookup.Keys.Where(p => p is T).ToList();
也适用于 GetAllOfType 的相似的变化

Unity ----- 对象池GameObjectPool的更多相关文章

  1. Unity 对象池 生产 保存

    Unity对象池主要是保存那些常用的物体,避免他们在不断销毁和创造中损坏性能. 主要思路为:创造物体时,判断是否存在,如果存在则调用并使其显示.如果不存在则创造一个新的. 当销毁时,调用协程延时隐藏物 ...

  2. Unity——对象池管理

    Unity对象池管理 一.Demo展示 二.逻辑 在游戏中会出现大量重复的物体需要频繁的创建和销毁:比如子弹,敌人,成就列表的格子等: 频繁的创建删除物体会造成很大的开销,像这种大量创建重复且非持续性 ...

  3. Unity 对象池的使用

    在游戏开发过程中,我们经常会遇到游戏发布后,测试时玩着玩着明显的感觉到有卡顿现象.出现这种现象的有两个原因:一是游戏优化的不够好或者游戏逻辑本身设计的就有问题,二是手机硬件不行.好吧,对于作为程序员的 ...

  4. Unity对象池的实现

    对象池是一个单例类: using System.Collections; using System.Collections.Generic; using UnityEngine; public cla ...

  5. 游戏设计模式——Unity对象池

    对象池这个名字听起来很玄乎,其实就是将一系列需要反复创建和销毁的对象存储在一个看不到的地方,下次用同样的东西时往这里取,类似于一个存放备用物质的仓库. 它的好处就是避免了反复实例化个体的运算,能减少大 ...

  6. Unity对象池管理

    链接: http://www.xuanyusong.com/archives/2925 http://www.xuanyusong.com/archives/2974 https://www.cnbl ...

  7. GameObjectPool——Unity中的对象池

    这里介绍一种对象池的写法.它的优点在于无论取出还是插入游戏物体都是常数量时间. using UnityEngine; using System.Collections; using System.Co ...

  8. Unity中对象池的使用

    unity中用到大量重复的物体,例如发射的子弹,可以引入对象池来管理,优化内存. 对象池使用的基本思路是: 将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用.恰当地使用对象池,可以在 ...

  9. Unity中的万能对象池

    本文为博主原创文章,欢迎转载.请保留博主链接http://blog.csdn.net/andrewfan Unity编程标准导引-3.4 Unity中的万能对象池 本节通过一个简单的射击子弹的示例来介 ...

随机推荐

  1. 图论:POJ2186-Popular Cows (求强连通分量)

    Popular Cows Description Every cow's dream is to become the most popular cow in the herd. In a herd ...

  2. DRF filter

    filter 配置 fiter定义 自定义filter继承BaseFilterBackend,必须重写filter_queryset,返回值为过滤后的queryset filter在GenericAP ...

  3. Python Jquery学习

    jquery调用方法: $(css的选择器).操作函数 语法格式: 操作函数: html      修改内容 点击button键后,jquery就会变为bootstrap 当然里面也可以进行判断,实现 ...

  4. jmeter结果分析详解

    Jmeter测试报表相关参数说明 采用Jmeter测试工具对web系统作的负载测试,得出的响应报表,数据比较难懂,现作一具体说明.以下是在一次具体负载测试中得出的具体数值,测试线程设置情况为:线程数: ...

  5. c#笔记2019-01-06

    using System; using System.Collections.Generic; using System.Linq; using System.Text; /*2019-01-06C# ...

  6. 使用Unity做2.5D游戏教程(二)

    最近在研究Unity 3D,看了老外Marin Todorov写的教程很详细,就翻译过来以便自己参考,翻译不好的地方请多包涵. 这是使用Unity 游戏开发工具制作一个简单的2.5D 游戏系列教程的第 ...

  7. BZOJ 2820 YY的GCD ——莫比乌斯反演

    我们可以枚举每一个质数,那么答案就是 $\sum_{p}\sum_{d<=n}\mu(d)*\lfloor n / pd \rfloor *\lfloor m / pd \rfloor$ 直接做 ...

  8. 转载:CreateMutex WaitForSingleObject ReleaseMutex使用

    HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes,// BOOL bInitialOwner,  // flag for init ...

  9. angular实时显示checkbox被选中的元素

    /** * Created by zh on 20/05/15. */ // Code goes here var iApp = angular.module("App", []) ...

  10. 解析XML字符串为json对象

    var overtime='<?xml version="1.0" encoding="UTF-8"?><response><co ...