由于学疏才浅,看不懂其中的奥妙,只会使用,在这里分享给大家,林老师牛逼~
/********************************用法说明************************
*
* ****************************(对象池工具)**********************
*
* **************************大吉大利,代码无bug ******************
*
* 使用InitResources方法把resources文件夹下所有物体生成对象池
*
* 如果不想生成全部的物体,使用InitResources<T>方法把resources文件夹下T类型物体生成对象池
*
* 如果不想生成Resources文件夹上面的物体 ,使用InitObject方法把一个具体的物体生成对象池
*
* 如果具体的物体很多的化,使用InitObjects方法把一堆具体的物体生成对象池
*
* 通过GetObj名字去对象池里面拿物体,默认的物体是不会自动回收的
*
* 如果要有自动回收功能,那么可以自己实现,也可以让物体挂上继承IRecyclable的脚本,但是代码要换成GetRecycleAbleObj
*
* 如果对回收时间不满意,可以自己重写IRecyclable里面的init方法,把时间改长一点
*
*
*******************************************菜鸟在线 林老师
*******************************************************2017年10月17日0:58
***************************************************************************/
using UnityEngine;
using System.Collections;
using System;
using System.Reflection;
using System.Collections.Generic;
namespace UnityEnginePool
{
public class ObjectPool
{
#region 单例模式
private static ObjectPool _instance;
public static ObjectPool Instance
{
get
{
if (_instance == null)
{
_instance = new ObjectPool();
}
return _instance;
}
}
#endregion
#region 成员变量
private object ct;
private MethodInfo me;
//所有生成对象池的库
public List<Stack<GameObject>> mList = new List<Stack<GameObject>>();
//所有生成对象池的物体的字典,用于查询是否生成过,还有查询物体的下标
public Dictionary<string, int> mDic = new Dictionary<string, int>();
#endregion
#region 构造函数
/// <summary>
/// 构造函数私有化
/// </summary>
private ObjectPool()
{
//获取这个类
Type ty = typeof(Creator);
me = ty.GetMethod("Create");
ct = Activator.CreateInstance(ty);
}
#endregion
#region 泛型类型初始化到对象池
/// <summary>
/// 将Resources文件夹下所有T类型的物体实例化到对象池
/// </summary>
/// <param name="count">要生成的数量.</param>
/// <typeparam name="T">写上你要实例化物体的类型.</typeparam>
public void InitResources<T>(int count) where T : MonoBehaviour
{
T[] objs = Resources.LoadAll<T>("");
for (int i = 0; i < objs.Length; i++)
{
InitObject<T>(objs[i], count);
}
}
/// <summary>
/// 将T类型的单个物体实例化到对象池
/// </summary>
/// <param name="obj">要实例化的物体.</param>
/// <param name="count">要生成的数量.</param>
/// <typeparam name="T">写上你要实例化物体的类型.</typeparam>
public void InitObject<T>(T obj, int count) where T : MonoBehaviour
{
if (mDic.ContainsKey(obj.name))
{
return;
}
object[] o = new object[2];
o[0] = obj.gameObject;
o[1] = count;
GameObject[] objs = (GameObject[])me.Invoke(ct, o);
Stack<GameObject> stack = new Stack<GameObject>();
for (int i = 0; i < objs.Length; i++)
{
objs[i].gameObject.SetActive(false);
stack.Push(objs[i]);
}
mList.Add(stack);
mDic.Add(obj.name, mList.Count - 1);
}
/// <summary>
/// 将T类型的多个物体实例化到对象池
/// </summary>
/// <param name="obj">要实例化的物体的数组.</param>
/// <param name="count">要生成的数量.</param>
public void InitObjects<T>(T[] obj, int count) where T : MonoBehaviour
{
for (int i = 0; i < obj.Length; i++)
{
InitObject<T>(obj[i], count);
}
}
#endregion
#region 普通类型初始化到对象池
/// <summary>
/// 将Resources文件夹下所有GameObject类型的物体实例化到对象池
/// </summary>
/// <param name="要生成的数量">Count.</param>
public void InitResources(int count)
{
GameObject[] objs = Resources.LoadAll<GameObject>("");
for (int i = 0; i < objs.Length; i++)
{
InitObject(objs[i], count);
}
}
/// <summary>
/// 将GameObject类型的单个物体实例化到对象池
/// </summary>
/// <param name="obj">要实例化的物体.</param>
/// <param name="count">要生成的数量.</param>
public void InitObject(GameObject obj, int count)
{
if (mDic.ContainsKey(obj.name))
{
return;
}
object[] o = new object[2];
o[0] = obj;
o[1] = count;
GameObject[] objs = (GameObject[])me.Invoke(ct, o);
Stack<GameObject> stack = new Stack<GameObject>();
for (int i = 0; i < objs.Length; i++)
{
objs[i].gameObject.SetActive(false);
stack.Push(objs[i]);
}
mList.Add(stack);
mDic.Add(obj.name, mList.Count - 1);
}
/// <summary>
/// 将GameObject类型的单个物体补充到不够的对象池里
/// </summary>
/// <param name="obj">要实例化的物体.</param>
/// <param name="count">要生成的数量.</param>
private void SuppleObject(Stack<GameObject> st, GameObject obj, int count)
{
Debug.Log("补充");
object[] o = new object[2];
o[0] = obj;
o[1] = count;
GameObject[] objs = (GameObject[])me.Invoke(ct, o);
for (int i = 0; i < objs.Length; i++)
{
objs[i].gameObject.SetActive(false);
st.Push(objs[i]);
}
}
/// <summary>
/// 将GameObject类型的多个物体实例化到对象池
/// </summary>
/// <param name="obj">要实例化的物体的数组.</param>
/// <param name="count">要生成的数量.</param>
public void InitObjects(GameObject[] obj, int count)
{
for (int i = 0; i < obj.Length; i++)
{
InitObject(obj[i], count);
}
}
#endregion
/// <summary>
/// 根据名字拿一个物体
/// </summary>
/// <returns>从对象池拿到的物体 .</returns>
/// <param name="name">物体的名字.</param>
public GameObject GetObj(string name)
{
if (!mDic.ContainsKey(name))
{
Debug.LogError("对象池获取失败!!" + "对象池没有你要的这个物体");
return null;
}
GameObject obj = mList[mDic[name]].Pop();
if (mList[mDic[name]].Count < 2)
{
SuppleObject(mList[mDic[name]], obj, 10);
}
obj.gameObject.SetActive(true);
return obj;
}
/// <summary>
/// 根据名字拿一个IRecycleAble的物体
/// </summary>
/// <returns>从对象池拿到的物体 .</returns>
/// <param name="name">物体的名字.</param>
public GameObject GetRecycleAbleObj(string name)
{
if (!mDic.ContainsKey(name))
{
Debug.LogError("对象池获取失败!!" + "对象池没有你要的这个物体");
return null;
}
GameObject obj = mList[mDic[name]].Pop();
if (mList[mDic[name]].Count < 2)
{
SuppleObject(mList[mDic[name]], obj, 10);
}
obj.gameObject.SetActive(true);
obj.GetComponent<IRecyclable>().Init(mDic[name]);
return obj;
}
/// <summary>
/// 回收一个物体
/// </summary>
/// <param name="obj">要回收物体的GameObject.</param>
public void CallBack(GameObject obj)
{
if (!mDic.ContainsKey(obj.name))
{
Debug.Log("对象池回收失败!!" + obj.name + "不是从对象池出来的");
return;
}
int no = mDic[obj.name];
mList[no].Push(obj);
obj.gameObject.SetActive(false);
}
/// <summary>
/// 回收一个IRecycleAble的物体
/// </summary>
/// <param name="obj">要回收物体的GameObject.</param>
public void CallBackIRecycle(IRecyclable obj)
{
string name = obj.gameObject.name.Split('(')[0];
if (!mDic.ContainsKey(name))
{
Debug.Log("对象池回收失败!!" + name + "不是从对象池出来的");
return;
}
int no = mDic[name];
mList[no].Push(obj.gameObject);
obj.gameObject.SetActive(false);
}
}
public class Creator : MonoBehaviour
{
public GameObject[] Create(GameObject obj, int l)
{
GameObject[] o = new GameObject[l];
for (int i = 0; i < l; i++)
{
o[i] = Instantiate(obj);
}
return o;
}
}
public abstract class IRecyclable : MonoBehaviour
{
protected float mTime = 0.0f;
protected float Duration;
public float mDuration = 3.0f;
//初始化函数
public virtual void Init(int no)
{
NO = no;
mTime = mDuration;
}
//被回收的时候调用的函数
public virtual void OnRecycle()
{
ObjectPool.Instance.CallBackIRecycle(this);
}
public int NO;
void Update()
{
if (mTime > 0.0f)
{
mTime -= Time.deltaTime;
if (mTime < 0.0f)
{
OnRecycle();
}
}
}
}
}
网友评论