2D Enemy shooting in direction of player with object pool question

Hi,

I’m building a game where the enemy can shoot bullets in the direction of the player. Everything works fine until I try to use object pool for bullets with it.

Normally I would change velocity to instantiated bullet script on Update(), but in the case of bullets being shot in the direction of the player, if I did it, every bullet would keep on following player until it hit him. If I change velocity on Start(), it will apply only until first deactivation of instantiated bullet.

I’ve tried to put it OnEnable() instead, as I believe that’s the closest to what should be done, but then the enemy shoots bullets in all weird directions.

public class bullet : MonoBehaviour
{
    [SerializeField] float bulletForce = 5f;
    [SerializeField] float damage = 1f;
    [SerializeField] float timeToDeactivate = 7f;
    float timeSinceActivation;
    GameObject player;
    Rigidbody2D rb;
    PlayerHealth playerHealth;

    private void Awake()
    {
        player = GameObject.FindGameObjectWithTag("Player");
        rb = GetComponent<Rigidbody2D>();
        playerHealth = FindObjectOfType<PlayerHealth>();
    }
    private void OnEnable()
    {
        Vector2 direction = (player.transform.position - transform.position).normalized;
        rb.velocity = direction * bulletForce;
    }
    private void Update()
    {
        if (gameObject.activeInHierarchy)
        {
            timeSinceActivation += Time.deltaTime;
        }
        DeactivateAfterTime();
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("bullet")) return;
        if (collision.CompareTag("Enemy")) return;
        if (collision.CompareTag("Player"))
        {
            playerHealth.TakeDamage(damage);
        }
        gameObject.SetActive(false);
    }
    private void DeactivateAfterTime()
    {
        if (timeSinceActivation > timeToDeactivate) 
        {
            timeSinceActivation = 0;
            gameObject.SetActive(false);           
        }
    }
}
public class EnemyShooter : MonoBehaviour
{
    [SerializeField] float weaponRange = 10f;
    [SerializeField] Transform firePoint;
    [SerializeField] float timeBetweenAttacks = 1f;
    [SerializeField] GameObject player;

    float timeSinceLastAttack = 0f;

   

    private void Update()
    {
        Shoot();
    }

    private void Shoot()
    {
        timeSinceLastAttack += Time.deltaTime;
        float distanceToPlayer = Vector2.Distance(transform.position, player.transform.position);

        GameObject bullet = BulletsPool.instance.GetPulledObjects();

        if (timeSinceLastAttack > timeBetweenAttacks &&  distanceToPlayer < weaponRange)
        {
            if (bullet != null)
            {
                bullet.SetActive(true);
                bullet.transform.position = firePoint.position;
            }
            timeSinceLastAttack = 0f;
        }

      
    }
}
public class BulletsPool : MonoBehaviour
{
    public static BulletsPool instance;

    [SerializeField] GameObject bulletPrefab;

    List<GameObject> pooledObjects = new List<GameObject>();
    int poolSize = 5;

    private void Awake()
    {
        instance = this;
        PopulatePool();
    }

    private void PopulatePool()
    {
        

        for (int i = 0; i < poolSize; i++)
        {
            GameObject bullet = Instantiate(bulletPrefab, transform);
            pooledObjects.Add(bullet);
            bullet.SetActive(false);
        } 
    }

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

Any help would be appreciated :smiley:

You get a bullet from the pool. Just set the direction when you get the bullet.

I did just that and it worked. Thank you :smiley:

public class EnemyShooter : MonoBehaviour
{
    [SerializeField] Transform firePoint;
    [SerializeField] float weaponRange = 10f;
    [SerializeField] float shootForce = 7f;

    [SerializeField] Transform player;

    [SerializeField] float timeBetweenShots;
    float timeSinceLastShot;


    private void Update()
    {
        timeSinceLastShot += Time.deltaTime;

        Shoot();
    }

    private void Shoot()
    {
        float distanceToPlayer = Vector2.Distance(transform.position, player.position);
        GameObject bullet = BulletsPool.instance.GetPulledObjects();

        if ( distanceToPlayer < weaponRange && timeSinceLastShot > timeBetweenShots)
        {
            
            if (bullet != null )
            {
                bullet.SetActive(true);
                bullet.transform.position = firePoint.position;
                Vector2 direction = (player.position - firePoint.position).normalized;
                bullet.GetComponent<Rigidbody2D>().velocity = direction * shootForce;
            }
            timeSinceLastShot = 0;
        }
    }
}
1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.