Object pool
对象池
As the name implies, it is a container for storing objects. Mainly only suitable for scenes that require a large number of objects and are destroyed after use, such as bullets in shooting games, monsters in tower defense, and they are quickly destroyed after a large number of them are generated. Frequent generation and destruction of objects will consume a lot of cpu resources, cause the game to freeze, and the objects are stored in堆内存
discontinuous space, which will cause memory fragmentation problems. With the increase of running time, the program may crash.
Use a collection to store the objects to be mass-produced, and use a class to maintain the collection. There are mainly two methods GetObj
and Recycle
, used to provide objects and recycle objects
-
Simple implementation in unity
Scene building- Create a capsule, create an empty object as its child object, as the launch point of the bullet
- Create a Sphere sphere, and save it as a prefab, stored in the
Resources/Prefabs
namebullet
- Create a capsule, create an empty object as its child object, as the launch point of the bullet
Pool.cs
using UnityEngine
public class Pool
{
//单例模式实现
static Pool _instance;
public static Pool Instance
{
get
{
if(instance == null)
{
instance = new Pool();
}
return _instance;
}
}
GameObject _obj; //需要大量产生销毁的对象
List<GameObject> pool;
private Pool()
{
pool = new List<GameObject>();
//动态获取该对象
_obj = Resources.Load<GameObject>("Prefabs/bullet");
}
public GameObject GetObj()
{
GameObject obj;
if(pool.Count ==0)
{
//pool中没有存储对象时
obj = GameObject.instantiate(_obj);
obj.SetActive(false);
obj.AddComponent<Bullet>();
pool.Add(obj);
}
obj = pool[0]; //每次只取第一个
obj.SetActive(true);
//将提供的对象从pool中移除
pool.RemoveAt(0);
return obj;
}
public void Recycle(GameObject obj)
{
//将对象失活而不是Destory。然后存入到维护的pool中
obj.SetActive(false);
pool.Add(obj);
}
}
Bullet.cs
//继承MonoBehaviour
public class Bullet:MonoBehaviour
{
void OnEnable()
{
//一定要写在OnEnable中
StartCoroutine(Recycle());
}
void Update () {
transform.Translate(Vector3.forward * 10 * Time.deltaTime);
}
//使用协程完成自动回收,也可以使用计时器
IEnumerator Recycle()
{
yield return new WaitForSeconds(1f);
BulletPool.Instance.Recycle(gameObject);
}
}
Test.cs
//挂载在胶囊上面
public class Test:MonoBehaviour
{
void Start () {
}
void Update () {
if (Input.GetKeyDown(KeyCode.Space))
{
//按空格产生子弹
GameObject bullet = BulletPool.Instance.GetObj();
bullet.transform.position = transform.GetChild(0).position;
}
}
}