只针对资源Obj,不兼容脚本,后面会制作支持全类型的万能对象池
上代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool
{
private GameObject prefab;
private List<GameObject> poolObjs;
private string objPath;
private int totleSize;
public ObjectPool(string path, int initPoolSize, int totleSize)
{
poolObjs = new List<GameObject>();
objPath = path;
this.totleSize = totleSize;
prefab = Resources.Load<GameObject>(path);
if(prefab == null)
{
ProDebug.Logger.LogError("path not res!");
return;
}
for (int i = 0; i < initPoolSize; i++)
{
GameObject obj = GameObject.Instantiate(prefab);
Transform tran = obj.transform;
tran.parent = ObjectPoolManager.Obj.transform;
tran.localPosition = Vector3.zero;
tran.localRotation = Quaternion.identity;
obj.SetActive(false);
obj.name = prefab.name;
poolObjs.Add(obj);
}
}
public bool HasObj(GameObject obj)
{
return prefab.name == obj.name;
}
public GameObject GetObj()
{
int objCount = poolObjs.Count;
if(objCount > 0)
{
GameObject target = poolObjs[objCount - 1];
target.SetActive(true);
poolObjs.RemoveAt(objCount - 1);
return target;
}
if(prefab == null) prefab = Resources.Load<GameObject>(objPath);
if (prefab == null)
{
ProDebug.Logger.LogError("path not res!");
return null;
}
GameObject obj = GameObject.Instantiate(prefab);
obj.transform.parent = ObjectPoolManager.Obj.transform;
obj.name = prefab.name;
return obj;
}
public void RecycleObj(GameObject obj)
{
obj.SetActive(false);
if(poolObjs.Count >= totleSize)
{
GameObject.Destroy(obj);
obj = null;
return;
}
Transform tran = obj.transform;
if(tran.parent != ObjectPoolManager.Obj.transform)
{
tran.parent = ObjectPoolManager.Obj.transform;
}
tran.localPosition = Vector3.zero;
tran.localRotation = Quaternion.identity;
poolObjs.Add(obj);
}
public void DoDestroy()
{
prefab = null;
for (int i = 0; i < poolObjs.Count; i++)
{
GameObject obj = poolObjs[i];
GameObject.Destroy(obj);
obj = null;
}
poolObjs.Clear();
objPath = null;
totleSize = 0;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public struct ObjectPoolInfo
{
public string resPath;
public int initPoolSize;
public int totleSize;
public ObjectPoolInfo(string path, int size, int totleCount = 100)
{
resPath = path;
initPoolSize = size;
totleSize = totleCount;
}
}
public class ObjectPoolManager : MonoBehaviour
{
private static ObjectPoolManager _instance;
private static object _lock = new object();
private static GameObject _game;
public static GameObject Obj
{
get
{
if (_game == null)
{
GameObject go = GameObject.Find("ObjcetPoolManager");
if (go == null)
{
go = new GameObject();
go.name = "ObjcetPoolManager";
go.transform.position = Vector3.zero;
}
_game = go;
}
return _game;
}
}
public static ObjectPoolManager Instance
{
get
{
if (applicationIsQuitting)
{
ProDebug.Logger.LogError("已经销毁了");
return null;
}
lock (_lock)
{
if (_instance == null)
{
_instance = Obj.GetComponent<ObjectPoolManager>();
if (_instance == null)
{
_instance = Obj.AddComponent<ObjectPoolManager>();
}
}
return _instance;
}
}
}
private static bool applicationIsQuitting = false;
private Dictionary<string, ObjectPool> objectPools = new Dictionary<string, ObjectPool>();
private void Awake()
{
DontDestroyOnLoad(Obj);
}
public void OnDestroy()
{
applicationIsQuitting = true;
}
/// <summary>
/// 初始化需要的n个池子
/// </summary>
/// <param name="ObjectPoolInfos">池子数据列表</param>
public void InitPoos(List<ObjectPoolInfo> ObjectPoolInfos)
{
for (int i = 0; i < ObjectPoolInfos.Count; i++)
{
ObjectPoolInfo info = ObjectPoolInfos[i];
CreateObjectPool(info.resPath, info.initPoolSize, info.totleSize);
}
}
/// <summary>
/// 初始化池子
/// </summary>
/// <param name="info">池子数据</param>
public void InitPool(ObjectPoolInfo info)
{
CreateObjectPool(info.resPath, info.initPoolSize, info.totleSize);
}
/// <summary>
/// 创建池子
/// </summary>
/// <param name="resPath">池子资源路径</param>
/// <param name="initPoolSize">池子初始大小</param>
/// <returns></returns>
ObjectPool CreateObjectPool(string resPath, int initPoolSize, int totleSize)
{
if (objectPools.ContainsKey(resPath))
{
//ProDebug.Logger.LogError("对象池已经存在");
return null;
}
ObjectPool objectPool = new ObjectPool(resPath, initPoolSize, totleSize);
objectPools.Add(resPath, objectPool);
return objectPool;
}
/// <summary>
/// 从池子中获得物体
/// </summary>
/// <param name="resPath">物体路径</param>
/// <param name="initPoolSize">如果没初始化过池子,这里面默认创建,参数是池子初始大小</param>
/// <returns></returns>
public GameObject GetObj(string resPath, int initPoolSize = 1, int totleSize = 100)
{
ObjectPool pool = null;
if (objectPools.TryGetValue(resPath, out pool))
{
return pool.GetObj();
}
pool = CreateObjectPool(resPath, initPoolSize, totleSize);
if(pool == null)
{
ProDebug.Logger.LogError("resPath is null");
return null;
}
return pool.GetObj();
}
/// <summary>
/// 回收物体
/// </summary>
/// <param name="obj">物体实例</param>
public void RecycleObj(GameObject obj)
{
if (obj == null) return;
foreach (var item in objectPools)
{
ObjectPool pool = item.Value;
if (pool.HasObj(obj))
{
pool.RecycleObj(obj);
return;
}
}
}
/// <summary>
/// 删除制定池子
/// </summary>
/// <param name="resPath">池子资源</param>
public void DestroyPool(string resPath)
{
ObjectPool pool = null;
if(objectPools.TryGetValue(resPath, out pool))
{
pool.DoDestroy();
objectPools.Remove(resPath);
}
}
/// <summary>
/// 删除所有的池子
/// </summary>
public void DestroyAllPool()
{
foreach (var item in objectPools)
{
item.Value.DoDestroy();
}
objectPools.Clear();
}
}