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 