Unity object pool and the simplest implementation

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.

  • The overall idea of ​​the object pool

Use a collection to store the objects to be mass-produced, and use a class to maintain the collection. There are mainly two methods GetObjand Recycle, used to provide objects and recycle objects

  • Simple implementation in unity

    Scene building
    1. Create a capsule, create an empty object as its child object, as the launch point of the bullet
      Insert picture description here
    2. Create a Sphere sphere, and save it as a prefab, stored in the Resources/Prefabsnamebullet
      Insert picture description here

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;
        }
	}
}

Guess you like

Origin blog.csdn.net/weixin_36382492/article/details/88257275