Unity中对象池的应用
2016-10-15 11:34
363 查看
一、对象池思想
1.使用对象池的好处
很多情况下,我们需要创建大量对象,例如发射子弹,或者大量的AI小兵,不断重新的生成和销毁对象会对性能造成巨大的消耗,所以我们考虑使用对象池技术来管理需大量生成的对象。2.对象池的组成
对象池的核心包括对象池控制器类(ObjectCtrl)、对象池类(SubPool)以及对象池中具体存放的物品类(obj),当有多个对象时通过SubPool中的list集合进行管理,而当有多个对象池,则通过ObjectCtrl中的Dictionary集合进行管理ObjectCtrl
ObjectCtrl 好比仓库经理,而SubPool是具体的物品管理员。当你需要使用某件物品时去找仓库经理,仓库经理便通知物品管理员拿给你;当你需要借的物品种类仓库还没有,他则会招聘一个新的物品管理员(RegisterSubPool())。当然,物品的借出和归还你都是和仓库经理进行沟通的,不会直接接触下面的每个物品管理员。SubPool
SubPool负责具体的物品管理。当物品数量充足时,SubPool只要负责将已有的物品往外拿;当数量不够时,SubPool便会去购置更多物品,即增加对象池总的对象数量。SubPool中存放物品的最大数量等于你同时需要的最大数量,例如场景中同时最多只能产生100个小兵,那么负责管理小兵的对象池中最多就要放100个对象就OK了。obj类
具体的物品,拿出时需要将各种参数调好以保证正常使用,而归还时需要还原出厂设置便于下次借出。二、实现代码
1.ReuseObject接口
创建一个接口,用于限定对象池中所保存的对象的基本行为:public interface IReusable { void Spawn(); void UnSpawn(); }
对象池中的每个对象需要继承这个接口并实现接口中的方法,Spawn()方法是卵生物体之后所执行的操作,例如小怪属性的初始化;UnSpawn()方法回收物体之后所执行的操作,例如停止导航。
2.SubPool对象池类
对象池中的对象用List进行管理,便于动态扩展。对象池中保存的对象均为隐藏状态,当从对象池中获取对象后,该对象的状态变为显示,同时对象执行1中接口的Spawn()方法完成初始化。使用完毕后归还到对象池,状态变为隐藏,同时执行1中接口的UnSpaw())方法归0所有状态。public class SubPool { //对象集合 List<GameObject> m_pool = new List<GameObject>(); //预设体引用 GameObject m_prefab; public string Name { get { return m_prefab.name; } } public SubPool(GameObject prefab) { this.m_prefab = prefab; } public GameObject Spawn() { GameObject obj = null; foreach 4000 (GameObject x in m_pool) { if (!x.activeSelf) { //如果物体是隐藏的 obj = x; break; } } if (obj == null) { obj = GameObject.Instantiate(m_prefab); m_pool.Add(obj); } obj.SetActive(true); //物体显示出来 //执行物体的卵生方法 IReusable reusable = obj.GetComponent<IReusable>(); if (reusable != null) { reusable.Spawn(); } return obj; } //回收物体 public void UnSpawn(GameObject go) { if (m_pool.Contains(go)) { //执行物体的放回操作 IReusable reusable = go.GetComponent<IReusable>(); if (reusable != null) { reusable.UnSpawn(); } //隐藏 go.SetActive(false); } } //回收所有物体 public void UnSpawnAll() { foreach(GameObject go in m_pool) { if (go.activeSelf) { //执行物体的放回操作 IReusable reusable = go.GetComponent<IReusable>(); if (reusable != null) { reusable.UnSpawn(); } //隐藏 go.SetActive(false); } } } public bool Contains(GameObject go) { return m_pool.Contains(go); } }
3.ObjectCtrl 对象池控制器
如果有很多不同的物体则需要建立多个SubPool对象,当同时存在多个不同的对象池时,需要用控制器进行管理。用Dictionary集合存放所有的对象池,并用对象的名字进行索引。在使用时,即通过对象池控制器生成和释放具体的对象。public class ObjectPoolCtrl : MonoSingleton<ObjectPoolCtrl> { private Dictionary<string, SubPool> m_pools = new Dictionary<string, SubPool>(); //从对象池取物体 public GameObject Spawn(string name) { //查找对象池 SubPool pool; if (!m_pools.ContainsKey(name)) { RegisterSubPool(name); } //取出对应的对象池,并调用Spawn方法 pool = m_pools[name]; return pool.Spawn(); } //注册一个对象池 private void RegisterSubPool(string name) { GameObject prefab = Resources.Load<GameObject>(name); SubPool pool = new SubPool(prefab); m_pools.Add(pool.Name, pool); } public void UnSpawn(GameObject go) { foreach (SubPool pool in m_pools.Values) { if (pool.Contains(go)) { pool.UnSpawn(go); break; } } } }
相关文章推荐
- Unity中对象池的应用
- unity - 对象池技术的实现与应用
- Unity 对象池(Object Pooling)理解与简单应用
- 对象池的应用实例
- Unity 在MVC上的应用(中:Repository)
- 多层数据库应用基于Delphi DataSnap方法调用的实现-----------------对象池技术
- Java小对象的解决之道——对象池(Object Pool)的设计与应用
- Unity 在MVC上的应用(上:思路整理)
- [原创]Enterprise Library深入解析与灵活应用(3):倘若将Unity、PIAB、Exception Handling引入MVP模式.. .. ..
- android应用中加入admob(unity,eclipse均可)
- Unity 在MVC上的应用(扩展篇:JQuery AJAX)
- Java小对象的解决之道——对象池(Object Pool)的设计与应用
- Unity IOC容器的简单应用
- Unity制作的应用在android平台上的发布步骤
- ubuntu12下unity侧栏添加新应用!
- 关于对象池的应用
- Enterprise Library深入解析与灵活应用(7):再谈PIAB与Unity之间的集成
- Unity依赖注入容器的应用
- Unity依赖注入容器的应用
- Unity骨骼动力学应用