使用对象池之前的需求:
对象池真的是一种优化手段吗,它并不是适用大多情况,并且使用不当的话,反而得到相反的情况,内存和CPU反而消耗更大。
首先明确下对象池是什么?
对象池就是大量对象的集合,将它们都存入链表中。
对象池有什么作用?
当一定量的同类对象需要频繁的出现又消失时,为了避免频繁创建对象而造成效率低下,把符合消失条件的对象先不移除,等待下次使用时回收。
下面介绍一下对象池。1:对象池一般有会两个链表。一个是idle链表,一个是busy链表(就是创建一个类,里面有两个链表)。2:对外的接口一般有取出对象和回收对象两个。3:当你调用取出接口的时候,对象池会从idle里面拿出来一个返回给你并且把这个对象从idle里面删除掉添加到busy里。如果对象池发现idle是空的,对象池就会创建一个对象。然后把对象反给你并且把对象添加到busy里。4:当你调用回收接口的时候(注意把你要回收的对象传进去),对象池会把要回收的对象放到idle里并且从busy里移除掉。怎么样是不是很简单!
下面看一下实例!
代码:
首先创建一个对象池,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//对象池管理
public class ObjectPoolManager : MonoBehaviour {
//单列
public static ObjectPoolManager instance;
void Awake ()
{
instance = this;
}
private Dictionary<string, List> pool;
void Start () {
pool = new Dictionary<string, List>();
}
///
/// 取对象的方法
/// 预设体的名字池子的名字键值对的键名
/// 生成对象的坐标
/// 生成对象的角度
/// 得到的对象
//取对象的方法
public GameObject GetObjectFormPool(string objName,Vector3 pos ,Quaternion qua)
{
GameObject go;
//判断是否存在对应的池子(通过字典的键值对判断是否包含objname的键)
//,并判断池子里是否包含对象,有对象才能取出来(通过判断list里元素的个数,大于0则说明至少有一个)
if (pool.ContainsKey(objName) && pool[objName].Count > 0)
{
//从链表中取出第0个元素
go = pool[objName][0];
//并将第0个元素从链表中移除
pool[objName].RemoveAt(0);
//激活取出的对象
go.SetActive(true);
}
else
{
//加载预设体
go =Instantiate(Resources.Load(objName) as GameObject);
}
//赋值坐标
go.transform.position = pos;
//赋值角度
go.transform.rotation = qua;
return go;
}
//存对象的方法
public void PushObjectToPool (GameObject go)
{
//通过Instantiate生成的对象名字均为预设体名字加上(clone),所以需要切割
//才能得到真正预设体的名字
string prefabName = go.name.Split('(')[0];
//通过预设体的名字来判断是否已经有对应的池子,如果有直接将go放到池子中
if (pool.ContainsKey(prefabName))
{
pool[prefabName].Add(go);
}
//没有对应的池子,那就在pool中创建一租键值对,并将go放到新池子中
else
{
//创建键值对
pool[prefabName] = new List<GameObject>() {go};
}
//刚开始存入池子的 对象清零
go.GetComponent<Rigidbody>().velocity= Vector3.zero;
go.SetActive(false);
}
}
第二篇代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//脚本任意挂入一个object对象中
public class ObjectPool : MonoBehaviour {
const string redBullet = “Red”;
const string YellowBullet = “Yellow”;
//生成红色子弹的预设体
public GameObject redBulletPrefab;
public GameObject YellowBulletPrefab;
//红色子弹生成的位置
public Transform redBulletPos;
public Transform yellowBulletPos;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown(0))
{
GameObject go = ObjectPoolManager.instance.GetObjectFormPool(redBullet, redBulletPos.position, redBulletPos.rotation);
go.GetComponent<Rigidbody>().AddForce(go.transform .forward*500);
StartCoroutine(DestoryBullect(go));
}
if (Input.GetMouseButtonDown(1))
{
GameObject go = ObjectPoolManager.instance.GetObjectFormPool(YellowBullet, yellowBulletPos.position, yellowBulletPos.rotation);
go.GetComponent<Rigidbody>().AddForce(go.transform.forward * 500);
StartCoroutine(DestoryBullect(go));
}
}
/// <summary>
/// 使用协程调用让子弹在激活后1秒自动“销毁”(进入不激活状态)
/// </summary>
/// <param name="go"></param>
/// <returns></returns>
IEnumerator DestoryBullect (GameObject go)
{
yield return new WaitForSeconds(1);
go.GetComponent<Rigidbody>().velocity = Vector3.zero;
ObjectPoolManager.instance.PushObjectToPool(go);
}
}
这样就好啦!下次见!!!