- Home /
object pooling shoots all bullets at once
Im having trouble with object pooling. whenever i try shooting it shoots all the bullets at once instead of one at a time. any help? this is the code for the bullet:
public class Projectile : MonoBehaviour
{
[SerializeField] private float speed;
private float direction;
private bool hit;
private float lifetime;
private Animator anim;
private BoxCollider2D boxCollider;
private void Awake()
{
anim = GetComponent<Animator>();
boxCollider = GetComponent<BoxCollider2D>();
}
private void Update()
{
if (hit) return;
float movementSpeed = speed * Time.deltaTime * direction;
transform.Translate(movementSpeed, 0, 0);
lifetime += Time.deltaTime;
if (lifetime > 5) gameObject.SetActive(false);
}
private void OnTriggerEnter2D(Collider2D collision)
{
hit = true;
boxCollider.enabled = false;
anim.SetTrigger("Explode");
}
public void SetDirection(float _direction)
{
lifetime = 0;
direction = _direction;
gameObject.SetActive(true);
hit = false;
boxCollider.enabled = true;
float localScaleX = transform.localScale.x;
if (Mathf.Sign(localScaleX) != _direction)
localScaleX = -localScaleX;
transform.localScale = new Vector3(localScaleX, transform.localScale.y, transform.localScale.z);
}
private void Deactivate()
{
gameObject.SetActive(false);
}
}
and this is the code for the shooting:
public class Attacks : MonoBehaviour
{
private Movement movement;
[SerializeField] private float attackCooldown;
[SerializeField] private Transform gunPoint;
[SerializeField] private GameObject[] Bullet;
private Animator anim;
private Movement playerMovement;
private float cooldownTimer = Mathf.Infinity;
private void Awake()
{
anim = GetComponent<Animator>();
playerMovement = GetComponent<Movement>();
}
private void Update()
{
if (Input.GetMouseButton(0))
Attack();
cooldownTimer += Time.deltaTime;
}
private void Attack()
{
cooldownTimer = 1;
Bullet[FindFireball()].transform.position = gunPoint.position;
Bullet[FindFireball()].GetComponent<Projectile>().SetDirection(Mathf.Sign(transform.localScale.x));
}
private int FindFireball()
{
for (int i = 0; i < Bullet.Length; i++)
{
if (!Bullet[i].activeInHierarchy)
return i;
}
return 0;
}
}
Answer by Captain_Pineapple · May 12 at 09:40 AM
Hey there,
in general this issue is probably not really connected to your current poolign approach but instead to be found here:
if (Input.GetMouseButton(0))
This function checks if the mouse button is down.
Assuming you are running 60 Updates a second this will check if the mouse button is down every 1/60 seconds. So unless you are reallyreally quick this will always trigger multiple times per click.
What you want to do instead is
if (Input.GetMouseButtonDown(0))
Which will only trigger once per click.
As i see you wanted to solve this with a cooldown timer but that does not do anything related to fireing yet?
Apart from that an improvement suggestion if you change your current code to:
var BulletID = FindFireball();
Bullet[BulletID].transform.position = gunPoint.position;
Bullet[BulletID].GetComponent<Projectile>().SetDirection(Mathf.Sign(transform.localScale.x));
As this is way friendlier on performance.
Apart from this i'd also suggest that you make your object pooling more variable:
use a
List<GameObject> Bullets
instead of an array.if add a Prefab for your Bullet
if your
FindFireBall
function does not find a deactivated one -> have it instantiate a new one and add it to the List.
Why might this be better? Because down the road when more and more entities in a scene might find a fireball this could lead to a case where the fireball with the ID zero is constantly taken from its current location and respawned somewhere else.