博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一、unity3D对象池————单个对象在池中的创建
阅读量:5222 次
发布时间:2019-06-14

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

 

对象池:对象存储在一个池子中,当需要再次使用时取出,而不需要每次都实例化一个新的对象,将对象循环利用起来。当我们需要大量实例化对象时可采用对象池,如游戏中的子弹等物体,当我们玩射击类游戏时,要发射大量子弹,如果每发子弹直接通过Instantiate全部实例化(笔者在unity中试过大量Instantiate后不销毁,unity引擎直接崩溃了),当然还有打怪类游戏,小怪的生成等。

下面有个小例子

 

对象池脚本(单例脚本)主要有以下三个部分

 

1、创建一个集合,当做你的对象池,用来存储对象

 

2、一个取对象的方法

 

3、一个存对象的方法

 

一、创建一个对象池脚本ObjectPools,将脚本设置成单例(单例在Unity中经常使用到),不用挂在任何物体上

注:集合中Add(),添加后,自动添加在集合末尾  Remove()删除元素时,假设删除第一个元素,集合中的元素自动向前补位(详情看另一篇集合泛型)

1 public class ObjectPools : MonoBehaviour { 2     //创建集合作为对象池 3     List
pools = new List
(); 4 //单例 5 private static ObjectPools instance; 6 private ObjectPools() { } 7 public static ObjectPools GetInstance() 8 { 9 if (instance==null)10 {11 //创建一个名字为ShellPool的对象,并将单例脚本附上12 instance = new GameObject("ShellPool").AddComponent
();13 }14 return instance;15 16 }17 //从对象池中取对象18 public GameObject MyInstantiate(GameObject name)19 {20 //对象池中没有对象 实例化对象21 if (pools.Count==0)22 {23 return Instantiate(name, Vector3.zero, Quaternion.identity) as GameObject;24 }25 else26 {27 //如果池中有对象 取出第一个28 GameObject go = pools[0];29 //将对象设置激活状态30 go.SetActive(true);31 //从对象池中删除对象32 pools.Remove(go);33 return go;34 35 }36 }37 //向对象池存对象38 public void DelayInstantiate(GameObject name)39 {40 //隐藏对象41 name.SetActive(false);42 //放入对象池中(集合中)43 pools.Add(name);44 }45 }

二、创建一个GameManager脚本,控制物体生成(预制体放在Resources文件下)

1 public class GameManager : MonoBehaviour { 2     GameObject shellPrefab; 3     public void Awake() 4     { 5         //找到预制体 6         shellPrefab = Resources.Load("Part01/Prefabs/Shell") as GameObject;   7     } 8     private void Update() 9     {10         if (Input.GetMouseButtonDown(0))11         {12             //实例化对象13             ObjectPools.GetInstance().MyInstantiate(shellPrefab);           14         }15     }16 }

三、预制体脚本,挂在预制体上,控制子弹向前

1 public class Shell : MonoBehaviour { 2     Transform target; 3     private void OnEnable() 4     { 5         //找到要生成的对象的空物体 位置,将空物体位置赋给对象初始位置 6         target = GameObject.Find("GameBullet").transform; 7         transform.position = target.position; 8         //启动协程 延时两秒 9         StartCoroutine(DelayObject(2f));10     }11     private void Update()12     {13         //物体移动14         transform.Translate(Vector3.forward * Time.deltaTime * 10);15     }16     //协程 17     IEnumerator DelayObject(float time)18     {19         yield return new WaitForSeconds(time);20         //调用脚本 向对象池存对象21         ObjectPools.GetInstance().DelayInstantiate(gameObject);22     }23 24 }

 

小结:对象池创建一部分对象,使用对象后,不销毁对象,通过隐藏对象,让人感觉被销毁,待下次需要继续使用时,通过激活之前被隐藏的对象,减少了实例化消耗内存的缺点。但因为创建对象后,对象只是隐藏,未被销毁,在运行时,还是可能占用大量内存。

转载于:https://www.cnblogs.com/tang-fei/p/10182807.html

你可能感兴趣的文章
java8新特性之Optional类
查看>>
在Qt(C++)中使用QThread实现多线程
查看>>
11-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案微信小程序篇(微信配网配置_Airkiss步骤_2)...
查看>>
jquery阅读记录2
查看>>
zabbix电话告警V1
查看>>
eclipse把局部变量提为全局变量的快捷键是什么
查看>>
《研磨设计模式》——可配置的简单工厂
查看>>
为网站添加免费的访问计数统计和加入微博
查看>>
ubuntu root用户 默认密码
查看>>
对百度搜索法的分析评价
查看>>
网络知识之ipset
查看>>
Credit Memo和Debit Memo在AR以及AP中的概念比较
查看>>
在Azure上部署Sqlserver网络访问不了的问题
查看>>
hdu 1561 The more, The Better(树形dp入门)
查看>>
最小度限制生成树模板
查看>>
树状数组总结
查看>>
3.shell编程-文件查找之find命令
查看>>
SourceTree windows免注册免登陆使用方法
查看>>
Android Studio 快捷键和常用技巧汇总
查看>>
POJ 1195 Mobile phones(二维树状数组)
查看>>