对象池的基本定义大家基本了解了,我在这就进行简单的一句话概述。
通常情况下,当您实例化并销毁prefabs的实例,您在运行时不断创建新的对象和摧毁它们,这可能会导致运行时垃圾回收和偶尔的帧速率下降。对象池可以防止这种,通过预先实例化,而不是被摧毁然后重新生成对象!
本篇文章是关于unity内部的简单对象池实现,实现的基本功能就是,打死怪物后实例化金币,金币可以通过对象池一直复用。不需要重复的销毁金币和生成新的金币实例。
using System.Collections.Generic;
using UnityEngine;
namespace Logic.Base
{
//对象携带的脚本
public class BasePoolDataItem : MonoBehaviour{
public delegate object CollectHandler(GameObject obj);
public CollectHandler my_collect;
public float collect_time = 0;
void Start()
{ }
void Update()
{ }
void OnDestory()
{
Debug.LogError("OnDestory");
}
public virtual void StartState(CollectHandler _my_collect)
{
my_collect = _my_collect;
gameObject.SetActive(true);
if (collect_time != 0)
StartCoroutine(CollectMine());
}
public virtual void EndState()
{
gameObject.SetActive(false);
}
public IEnumerator CollectMine()
{
yield return new WaitForSeconds(collect_time);
Collect();
}
private void Collect()
{
if (my_collect != null)
my_collect(gameObject);
}
}
//对象携带的数据
public class BasePoolData{
Stack collect_stack;
List<GameObject> all_list;
public List<GameObject> All_List
{
get { return all_list; }
}
public Stack Collect_Stack
{
get { return collect_stack; }
}
public BasePoolData()
{
collect_stack = new Stack();
all_list = new List<GameObject>();
}
void OnDestory()
{
Debug.LogError("OnDestory");
}
}
//对象携带脚本
public class ObjectPool<T>where T: BasePoolDataItem{
public BasePoolData pool;
public ObjectPool()
{
pool = new BasePoolData();
}
public T GetBaseT(GameObject o)
{
T my_type = o.GetComponent<T>();
if (my_type == null)
my_type = (T)(o.AddComponent<T>());
return my_type;
}
//获取对象
public object GetObject(GameObject prefab,float collect_time = 0){
GameObject obj2 = null;
if (prefab == null)
{
Debug.LogError("GetObject prefab is null");
return obj2;
}
if (pool.Collect_Stack.Count > 0)
{
Stack stack = pool.Collect_Stack;
obj2 = (GameObject)stack.Pop();
}
else
{
obj2 = Object.Instantiate(prefab);
obj2.name = prefab.name;
pool.All_List.Add(obj2);
}
T my_type = GetBaseT(obj2);
my_type.collect_time = collect_time;
my_type.StartState(ReturnPool);
return obj2;
}
//对象回池
public object ReturnPool(GameObject o){
if (o == null)
{
Debug.LogError("ReturnPool gameobject is null");
return o;
}
if (!pool.Collect_Stack.Contains(o))
pool.Collect_Stack.Push(o);
T my_type = GetBaseT(o);
my_type.EndState();
return o;
}
public void AllReturnPool()
{
for (int i = 0; i < pool.All_List.Count; i++)
{
ReturnPool(pool.All_List[i]);
}
}
}
//不需要携带脚本的对象池
public class ObjectPool{
public BasePoolData pool;
public ObjectPool()
{
pool = new BasePoolData();
}
public object GetObject(GameObject prefab)
{
GameObject obj2 = null;
if (prefab == null)
{
Debug.LogError("GetObject prefab is null");
return obj2;
}
if (pool.Collect_Stack.Count > 0)
{
Stack stack = pool.Collect_Stack;
obj2 = (GameObject)stack.Pop();
}
else
{
obj2 = Object.Instantiate(prefab);
obj2.name = prefab.name;
pool.All_List.Add(obj2);
}
obj2.SetActive(true);
return obj2;
}
public object ReturnPool(GameObject o)
{
if (o == null)
{
Debug.LogError("ReturnPool gameobject is null");
return o;
}
if (!pool.Collect_Stack.Contains(o))
pool.Collect_Stack.Push(o);
o.SetActive(false);
return o;
}
public void AllReturnPool()
{
for (int i = 0; i < pool.All_List.Count; i++)
{
ReturnPool(pool.All_List[i]);
}
}
}
}