博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
对象池
阅读量:6680 次
发布时间:2019-06-25

本文共 3852 字,大约阅读时间需要 12 分钟。

第一次创建的时候就将对象存储在一个池子中,当需要销毁的时候不直接销毁而是隐藏,当需要时在再次使用,就不需要再次实例化一个新的对象,直接把隐藏的对象显示并拿出来用。如果对象池中已经被隐藏的物体太久没有被重新使用,应该被真正的销毁。

在这里插入图片描述
在这里插入图片描述
1. 首先,使用一个数据结构直接存储对象,为了降低装箱、拆箱操作,使用List来存储。
2. 其次,使用字典Dictionary<string,List>来存储多个对象。
3. 然后,从对象池中提取对象,如果对象池中已经存在,则激活该对象,并且从List集合中移除,否则,创建新的对象(OutPool方法实现该功能)。
4. 最后,将不用的对象再加入到对象池,加入之前,先判断该对象对应的键是否已经存在,如果存在,就直接添加进对应键的值中,否则,创建新的键值对。

一.创建Cube,创建一个Sphere(子弹)用于预制存储

创建对象池的脚本

public class GameObjectPool : MonoBehaviour{    const int number = 10;//子弹弹夹的容量    bool isin = true;//用来判断是否实例子弹对象    int n;//用来记录实例出子弹对象的个数    //集合里面的元素,相当于对象池里面的对象,这里的集合可看作为对象池。    static List
pools = new List
(); //再声明一个集合,用来回收发射出去的子弹对象 List
pb = new List
(); //首先创建一个单例 private GameObjectPool() { } private static GameObjectPool instance; public static GameObjectPool GetInstance(GameObject name)//此处的Gameobject name就是需要放入对象池的对象--子弹 { if (instance == null) { print("实例池子"); //动态的生成一个名为“GameObjectPool”的对象并将单例脚本附加上去 instance = new GameObject("GameObjectPool").AddComponent
(); for (int i = 0; i < number; i++)//先往对象池中放入十发子弹 { name.SetActive(false); pools.Add(name); } } return instance; } //从对象池中取对象 public GameObject MyInstantiate() { if (pools.Count == 0)//如果十发子弹打完 { print("没子弹了:" + pools.Count); return null; } else { // print(pools[0].name); //取出对象池里面的第一个元素 GameObject obj = pools[0]; if (isin)//判断是否已经实例了十发子弹 { //obj = pools[0]; Instantiate(obj);//实例出子弹 n++;//计数加加 if (n == number) { isin = false; } } //将对象设置为激活状态 obj.SetActive(true); //将被取出的元素,从对象池中移除 pools.Remove(obj); return obj; } } //回收子弹的方法 public void MyDisable(GameObject name) { //将传进来的对象隐藏(处于非激活状态) name.SetActive(false); //回收子弹添加到pb集合中 pb.Add(name); } public void ResetBullet()//换弹夹的方法 { if (pb.Count != 0)//判断回收子弹的集合是否是空 { print("pb不是空"); for (int i = 0; i < pb.Count; i++) { pools.Add(pb[i]); //把回收的子弹重新加到弹夹中去 } pb.Clear(); } }}

创建预制子弹的脚本(脚本挂载于Shpere预制上)

public class Bullet : MonoBehaviour{    //public Transform target;    void OnEnable()    {        //脚本可用的时候,重置子弹的位置。        //如果不加这句代码,从对象池中取出的子弹就会从上一次消失的位置开始运动。而不是你设定的子弹生成位置        //transform.position = Vector3.zero;        //开启协程方法        StartCoroutine(DelayDisable(3f));    }    void Update()    {        //子弹生成,自动向前运动        transform.Translate(Vector3.forward * Time.deltaTime * 20);    }    void OnDisable()    {        Debug.Log("I'm over");    }    //子弹消失的方法    IEnumerator DelayDisable(float time)    {        //等待三秒        yield return new WaitForSeconds(time);        //调用单例中向对象池里面存对象的方法       GameObjectPool.GetInstance(gameObject).MyDisable(gameObject);           }}

创建Cube的脚本,用于发射子弹(挂载于Cube上)

public class GameManerge : MonoBehaviour{    //创建子弹的预设体    public GameObject mBulletPrefab;    void Update()    {        //如果按下鼠标左键,发射子弹        if (Input.GetMouseButtonDown(0))        {            //调用单例脚本里面的从对象池中取对象的方法            GameObject go = GameObjectPool.GetInstance(mBulletPrefab).MyInstantiate();            if (go != null)            {                go.transform.position = transform.position;    //设置子弹生成的位置是Cube的位置                       }        }        //按下鼠标右键,换弹夹        if (Input.GetMouseButtonDown(1))        {            print("换子弹:");            GameObjectPool.GetInstance(mBulletPrefab).ResetBullet();        }    }}

在这里插入图片描述

转载地址:http://tcrxo.baihongyu.com/

你可能感兴趣的文章
springmvc源码解析之配置加载ContextLoadListener
查看>>
网站安全防护工作
查看>>
如何判断一个以太坊地址是不是合约?
查看>>
逆袭!? 期待下一个“BCH”出现
查看>>
opengl es3.0学习篇五:图元装配跟光栅化
查看>>
Qt之添加菜单项&状态栏
查看>>
负载均衡在分布式架构中是怎么玩起来的?
查看>>
Java程序员在工作的同时应该具备什么样的能力?
查看>>
Dubbo深入分析之Cluster层
查看>>
分析Padavan源代码,二
查看>>
WordPress的WPML外挂出问题恐出现安全漏洞
查看>>
Django 调试技巧
查看>>
Spring Boot和thymeleaf , freemarker , jsp三个前端模块的运用
查看>>
phalcon-入门篇3(优美的URL与Config)
查看>>
单表60亿记录等大数据场景的MySQL优化和运维之道
查看>>
sql学习笔记
查看>>
maven编译时出现There are test failures
查看>>
SpringBoot | 第三十一章:MongoDB的集成和使用
查看>>
网络学习笔记2
查看>>
JPA--多对多关系
查看>>