有很长时间没有写博客了,工作太忙。加上写一些简单的东西实在没有欲望。本文介绍一个轻便易用的对象池脚本。
一个对象池需要向外界提供如下功能:
1:从池里拿一个(几个)出来
2:将一个(几个)没用的对象扔回池里
让外界只关心两件事:从池里取和放回池里
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//池 公共的,以active来表示对象是否空闲
public class ObjPool : MonoBehaviour
{
public GameObject prefab1;
public GameObject prefab2;
public GameObject prefab3;
List<GameObject> pool1;
List<GameObject> pool2;
List<GameObject> pool3;
Transform mainCanvas; //暂时用mainCanvas作为空闲对象的父物体,以后可修改
void Awake()
{
if (pool1==null)
{
pool1 = new List<GameObject>();
}
if (pool2 == null)
{
pool2 = new List<GameObject>();
}
if (pool3 == null)
{
pool3 = new List<GameObject>();
}
mainCanvas = GameObject.FindWithTag("mainCanvas").transform;
}
//从池里拿一个
public GameObject GetObj_1() {
for (int i = 0; i < pool1.Count; i++)
{
if (!pool1[i].activeInHierarchy)
{
pool1[i].SetActive(true);
return pool1[i];
}
}
GameObject tempObj = Instantiate(prefab1);
tempObj.SetActive(true);
pool1.Add(tempObj);
return tempObj;
}
public GameObject GetObj_2()
{
for (int i = 0; i < pool2.Count; i++)
{
if (!pool2[i].activeInHierarchy)
{
pool2[i].SetActive(true);
return pool2[i];
}
}
GameObject tempObj = Instantiate(prefab2);
tempObj.SetActive(true);
pool2.Add(tempObj);
return tempObj;
}
public GameObject GetObj_3()
{
for (int i = 0; i < pool3.Count; i++)
{
if (!pool3[i].activeInHierarchy)
{
pool3[i].SetActive(true);
return pool3[i];
}
}
GameObject tempObj = Instantiate(prefab3);
tempObj.SetActive(true);
pool3.Add(tempObj);
return tempObj;
}
//将某个Obj放回池
public void ThrowOneToPool(GameObject obj) {
bool exit = false;
for (int i = 0; i < pool1.Count; i++)
{
if (pool1[i]==obj)
{
exit = true;
}
}
for (int i = 0; i < pool2.Count; i++)
{
if (pool2[i]==obj)
{
exit = true;
}
}
for (int i = 0; i < pool3.Count; i++)
{
if (pool3[i]==obj)
{
exit = true;
}
}
if (!exit)
{
return;
}
obj.SetActive(false);
//obj.transform.SetParent(Transform.)
obj.transform.parent = mainCanvas;
}
//将所有对象放回池
public void ThrowAllToPool() {
for (int i = 0; i < pool1.Count; i++)
{
pool1[i].SetActive(false);
pool1[i].transform.parent = mainCanvas;
}
for (int i = 0; i < pool2.Count; i++)
{
pool2[i].SetActive(false);
pool2[i].transform.parent = mainCanvas;
}
for (int i = 0; i < pool3.Count; i++)
{
pool3[i].SetActive(false);
pool3[i].transform.parent = mainCanvas;
}
}
void OnDestroy()
{
if (pool1 != null)
{
for (int i = 0; i < pool1.Count; i++)
{
Destroy(pool1[i]);
}
}
pool1 = null;
if (pool2 != null)
{
for (int i = 0; i < pool2.Count; i++)
{
Destroy(pool2[i]);
}
}
pool2 = null;
if (pool3 != null)
{
for (int i = 0; i < pool3.Count; i++)
{
Destroy(pool3[i]);
}
}
pool3 = null;
}
}
非常轻便实用,用的时候需要将此脚本挂载在某个对象身上,这个池支持三种对象,举个例子就是:子弹,火焰,飞刀。角色发射子弹就可以在池里反复拿取,用完再扔回池里。
假设我想在想发射一枚子弹,则调用 GetCompoment<ObjPool>().GetObj_1(); 获取一枚子弹。当子弹打到某个物体,发挥玩作用后,调用 池脚本的 ThrowOneToPool方法将子弹收回池里。
另外,池还提供将所有对象放回池里的方法 ThrowAllToPool 方法。
外界只关心获取一个对象,将对象放回去 这两件事。 而创建 销毁 复用这三件事让池来做。
以上就是一个简单实用的对象池工具