对象池使用
2017-07-05 08:36
155 查看
对象池:对象池就存放需要被反复调用资源的一个空间,当一个对象回大量生成的时候如果每次都销毁创建会很费时间,通过对象池把暂时不用的对象放到一个池中
(也就是一个集合),当下次要重新生成这个对象的时候先去池中查找一下是否有可用的对象,如果有的话就直接拿出来使用,不需要再创建,如果池中没
有可用的对象,才需要重新创建,利用空间换时间来达到游戏的高速运行效果,在FPS游戏中要常被大量复制的对象包括子弹,敌人,粒子等
把脚本分别拖入场景中,不需要做任何操作
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//创建接口,用于传递对象的生成和销毁
public interface IControl{
//生成时调用
void Spawn ();
//销毁对象
void UnSpawn ();
}
/// <summary>
/// 对象池类,用于存放相同类型的对象
/// 1.从对象池中拿出一个游戏对象
/// 2.回收某一个游戏对象
/// 3.回收所有的游戏对象
/// 4.检查某个游戏对象是否在对象池里
/// </summary>
/// //对象池类
public class SubPool {
//对象池里存放的所有需要频繁创建销毁的游戏对象
List <GameObject> pool = new List<GameObject>();
//要创建的游戏对象的预设体
GameObject prefab;
//返回预制体的名字,预制体的名字和对象池的名字一致,在管理对象池的时候
//可以通过预制体的名字找到相应的对象池
public string name{
get{
return prefab.name;
}
}
//自定义一个构造函数
public SubPool(GameObject obj){
prefab = obj;
}
//从对象池里面拿出一个游戏对象
public GameObject SubPoolSpawn(){
GameObject obj = null;
//遍历集合,如果有对象就拿来用,没有的话,直接创建,放进池子
foreach (GameObject item in pool) {
//如果没有用(场景中没有显示)
if (item.activeSelf == false) {
//取出
obj = item;
break;
}
}
//说明当前游戏对象没有可复用的游戏对象(有两种情况,一个没有,一个全部再用)
if (obj == null) {
//创建游戏对象,放在池子里
obj = GameObject.Instantiate (prefab) as GameObject;
pool.Add (obj);
}
// 将游戏对象设置为激活状态
obj.SetActive (true);
IControl control = obj.GetComponent<IControl> ();
if (control != null) {
control.Spawn ();
}
return obj;
}
//回收某一个游戏对象
public void SubPoolUnSpawn(GameObject obj){
//如果包含该游戏对象
if (pool.Contains(obj)) {
obj.SetActive (false);
IControl control = obj.GetComponent<IControl> ();
if (control != null) {
control.UnSpawn ();
}
}
}
//回收所有的游戏对象
public void SubPoolUnSpanwAll(){
//遍历所有未激活的游戏对象,进行回收
foreach (GameObject item in pool) {
if (item.activeSelf) {
SubPoolUnSpawn (item);
}
}
}
//检查某个对象是否在对象池里
public bool SubPoolContains(GameObject obj){
return pool.Contains (obj);
}
}
把脚本分别拖入场景中,不需要做任何操作
using System.Collections; using System.Collections.Generic; using UnityEngine; //管理类 public class PoolControl { #region单利 private static PoolControl instance; private PoolControl (){ } public static PoolControl Instance{ get{ if (instance == null ) { instance = new PoolControl (); } return instance; } } #endregion //创建字典,根据预设体的名字,找到对应的对象池 Dictionary<string, SubPool> PoolDir = new Dictionary<string, SubPool> (); //添加对象池的方法 private void Register(string name){ //通过名字加载预制体 GameObject obj = Resources.Load (name) as GameObject; //根据预制体创建相应的对象池对象 SubPool subPool = new SubPool(obj); //将obj对象池对象添加到对象池管理类字典里 PoolDir.Add (name, subPool); } //根据预制体的名字找到对象池的对象,调用对象池中返回游戏对象的方法 public GameObject Spawn (string name){ SubPool subPool; //如果字典中不包含对应的key为name的键值对 if (!PoolDir.ContainsKey(name)) { //此时需要在字典中创建对应的对象池 Register (name); } subPool = PoolDir [name]; return subPool.SubPoolSpawn (); } //回收一个游戏对象的方法 public void UnSpwan(GameObject obj){ //找对游戏对象所在的池子 foreach (SubPool item in PoolDir.Values) { if (item.SubPoolContains(obj)) { //让该对象池回收它 item.SubPoolUnSpawn (obj); break; } } } }
创建一个Sphere球,把bittle脚本挂在Sphere身上,并把Sphere重命名为Butttle, 并把Buttle拖成预设体,放在Resources文件中
using System.Collections; using System.Collections.Generic; using UnityEngine; public class bittle : MonoBehaviour,IControl { //实现接口里面的方法 public void Spawn () { Debug.Log("表示从对象池中生成"); //从游戏对象创建开始执行,延迟3秒销毁 Invoke ("DeleteSelf", 3); } public void UnSpawn () { Debug.Log("表示从对象池中销毁"); } void Start () { } void Update () { transform.position += Time.deltaTime * Vector3.forward * 20; } //子弹销毁 void DeleteSelf(){ //回收游戏对象 PoolControl.Instance.UnSpwan (gameObject); //重置一下位置 transform.position = Vector3.zero; } }
创建一个胶囊体,并把player脚本挂在身上,运行的时候,按下空格的时候发射子弹
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { if (Input.GetKeyDown(KeyCode.Space)) { //创建子弹 GameObject obj = PoolControl.Instance.Spawn ("Bullet"); obj.transform.position = transform.position; } } }
相关文章推荐
- Using object pools(使用对象池)
- 使用.net技术创建一个小型对象池
- cocos2d-x 对象池机制:可回收与重复使用
- NGUI UIScrollView卡顿,使用对象池性能优化
- commons-pool2对象池使用
- Unity3D中对象池的使用
- 编写高效的C++程序方法之使用对象池
- Unity3D中对象池的使用
- unity3d对象池的使用
- 对象池(对象缓冲池)--采用最近最久未使用策略管理对象,同时带有事件监听功能
- 对象池的使用
- 编写高效的C++程序方法之使用对象池
- 对象池使用时要注意几点
- java对象池的使用
- 使用.net技术创建一个小型对象池
- 简单构建一个xmlhttp对象池合理创建和使用xmlhttp对象
- 什么情况下应该使用对象池(ObjectPool)?
- 编写高效的C++程序方法之使用对象池
- 对象池技术apache-common pool的使用
- [置顶] unity中对象池的使用