大家好,欢迎来到IT知识分享网。
先讲一下我对对象池的理解吧,说白了就是有一个两个集合和一个要存储的物体,一个是存储着激活的物体的,一个是存储着未激活的,要拿物体的时候先去未激活的里面找,如果有就返回然后从未激活的列表移除,然后在激活列表添加,如果未激活的列表里没有物体就那存储的物体实例一个存到激活的列表里.
再说一下对象池要实现的功能吧,说白了就是增删查和清除,分三个方法
第一个就是一个取物体的方法,先查找未激活列表有东西吗(这里用到一个查找的方法),如果没有就创建一个(这里需要一个增加的方法),第二个是放回的方法,放回的时候从激活列表移除在未激活列表添加,第三个就是清理方法,把两个列表里存储的物体给Destory掉,然后把两个列表清空
废话不多说,上代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool
{
public List<GameObject> activeObj = new List<GameObject>(); // 激活的
public List<GameObject> inactiveObj = new List<GameObject>(); // 未激活的
public GameObject prefab; // 要储存的预设
private int objectsNum = 0;
public int ObjectsNum {
get {
return objectsNum;
}
protected set {
objectsNum = value;
}
}
public ObjectPool(GameObject prefab)
{
if (prefab != null)
{
objectsNum = 0;
this.prefab = prefab;
}
}
public GameObject Creat()
{
if (prefab != null)
{
GameObject newObj = Object.Instantiate(prefab, Vector3.zero, Quaternion.identity);
if (newObj != null)
{
Object.DontDestroyOnLoad(newObj);
objectsNum++;
return newObj;
}
}
return null;
}
public GameObject TakeObj()
{
if (prefab != null)
{
GameObject newObj;
if (inactiveObj.Count > 0)
{
newObj = inactiveObj[0];
inactiveObj.RemoveAt(0);
}
else
{
newObj = Creat();
}
if (newObj != null)
{
activeObj.Add(newObj);
SetActive(newObj, true);
}
return newObj;
}
return null;
}
public void Restor(GameObject obj, Transform savePanel, bool destory = false)
{
if (obj != null)
{
if (activeObj.Contains(obj))
{
activeObj.Remove(obj);
if (destory)
{
Destory(obj);
}
else
{
obj.transform.SetParent(savePanel);
SetActive(obj, false);
inactiveObj.Add(obj);
}
}
}
}
private void Destory(GameObject go)
{
if (go != null)
{
Object.Destroy(go);
objectsNum--;
if (objectsNum < 0)
{
objectsNum = 0;
}
}
}
private void SetActive(GameObject go, bool active)
{
if (go != null && go.activeSelf != active)
{
go.SetActive(active);
}
}
public void Release()
{
if (inactiveObj.Count > 0)
{
for (int i = 0; i < inactiveObj.Count; i++)
{
Destory(inactiveObj[i]);
}
}
if (activeObj.Count > 0)
{
for (int i = 0; i < activeObj.Count; i++)
{
Destory(activeObj[i]);
}
}
inactiveObj.Clear();
activeObj.Clear();
objectsNum = 0;
prefab = null;
}
}
当然了,对象池也要有个管理器,管理着所有的对象池,管理器有一个键值对,存储着所有的对象池,key是存储的对象,value是存储对象的对象池,对象池的管理者有得到对象的接口(同上如果没有就出创建),有个放回对象的接口,还有个释放(清理)所有的接口
代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPoolMgr : MonoBehaviour
{
public static ObjectPoolMgr Instance {get;protected set;}
protected Dictionary<GameObject, ObjectPool> pools = new Dictionary<GameObject, ObjectPool>();
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
}
/// <summary>
/// 从对象池取值(如果没有对象池就创建一个)
/// </summary>
/// <param name="prefab">对象池集合的key</param>
/// <returns></returns>
public GameObject GetObj(GameObject prefab)
{
if (prefab != null)
{
ObjectPool pool = GetPool(prefab);
if (pool == null)
{
pool = Creat(prefab);
}
if (pool != null)
{
return pool.TakeObj();
}
}
return null;
}
private ObjectPool GetPool(GameObject prafab)
{
if (prafab != null)
{
ObjectPool pool;
return pools.TryGetValue(prafab, out pool) ? pool : null;
}
return null;
}
private ObjectPool Creat(GameObject prefab)
{
if (prefab != null)
{
ObjectPool pool = new ObjectPool(prefab);
pools.Add(prefab, pool);
return pool;
}
return null;
}
/// <summary>
/// 放回对象池或者销毁
/// </summary>
/// <param name="go">要放回对象池或者销毁的对象</param>
/// <param name="destory"></param>
public void Restor(GameObject go, bool destory = false)
{
if (pools.Count > 0)
{
var pool = pools.GetEnumerator();
while (pool.MoveNext())
{
Restor(pool.Current.Key, go, destory);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="prefab">对象池集合的Key</param>
/// <param name="go">对象池的key</param>
/// <param name="destory"></param>
private void Restor(GameObject prefab, GameObject go, bool destory)
{
ObjectPool pool = GetPool(prefab);
if (pool != null)
{
pool.Restor(go, transform, destory);
}
}
public void Release()
{
if (pools.Count > 0)
{
List<GameObject> keys = new List<GameObject>();
keys.AddRange(pools.Keys);
for (int i = 0; i < keys.Count; i++)
{
ReleasePool(keys[i]);
}
}
pools.Clear();
}
private void ReleasePool(GameObject prefab)
{
ObjectPool pool = GetPool(prefab);
if (pool != null)
{
pool.Release();
}
}
}
就这样一个对象池就写好啦~
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/10766.html