Shooting in Unity with Bullet Pool

This time we will make shooting functionality based on pooling. This way we can keep shooting without performance loss. It works this way:
We create few bullets at the very start of our game and hide them from the view. Whenever we shoot the bullet is taken from that pool, becomes visible and flies to the target. When it hits the target or when some time passes we can deactivate the bullet and return to the pool. This process goes over and over again.

BulletPool and Shoot scripts are to be attached to the shooting object in the game.

Bullet script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour
{
    void OnEnable() {
        StartCoroutine(nameof(ReturnToPool), 1f);
    }

    IEnumerator ReturnToPool(float time){
        yield return new WaitForSeconds(time);
        gameObject.SetActive(false);
    }

    void OnCollisionEnter2D(Collision2D other) {
        StartCoroutine(nameof(ReturnToPool), 0.2f);
    }
}

BulletPool script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BulletPool : MonoBehaviour
{
    [SerializeField] GameObject bulletPrefab;
    List<GameObject> bulletPoolList = new List<GameObject>();
    int amountToPool = 6;
    void Start(){
        for (int i = 0; i < amountToPool; i++){
            GameObject bullet = Instantiate(bulletPrefab);
            bullet.SetActive(false);
            bulletPoolList.Add(bullet);
        }
    }

    public GameObject GetBullet(){
        for (int i = 0; i < bulletPoolList.Count; i++){
            if(!bulletPoolList[i].activeInHierarchy){
                return bulletPoolList[i];
            }
        }
        return null;
    }
}

Shoot script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Shoot : MonoBehaviour
{
    [SerializeField] Transform aim;
    BulletPool bulletPool;
    ParticleSystem ps;
    void Start(){
        ps = GetComponentInChildren<ParticleSystem>();
        bulletPool = GetComponent<BulletPool>();
    }

    void Update(){
        if(Input.GetButtonDown("Fire1")){
            ShootBullet();
        }
    }

    void ShootBullet(){
        if(bulletPool){
            GameObject bullet = bulletPool.GetBullet();
            if(bullet){
                ps.Play();
                bullet.transform.position = aim.position;
                bullet.transform.rotation = Quaternion.Euler(Vector3.zero);
                bullet.SetActive(true);
                bullet.GetComponent<Rigidbody2D>().AddForce(new Vector2(10f, 0f), ForceMode2D.Impulse);
            }
        }
    }
}

Leave a Comment

Your email address will not be published. Required fields are marked *