1
votes

I'm having this problem with my enemy shooting, you see I'm using raycasting to detected where my player is and once detected I want the enemy to shoot, so far I have accomplished that but however there's not delay between each Instantiated bullet!So the bullet is being constantly spawn rather than a delay in between each spawn. I've tried a whole lot of different solutions to fix this problem but nothing worked! I've tried IEnumerator, object pooling, creating a count down timer and invoke & invokerepeating but still my bullets are still being instantiated instantly without no delay. Does any one knows how to have a delay between each instantiated bullet?? Thank you!

This is my script:

public GameObject bulletPrefab;
public Transform bulletSpawn;
public Transform sightStart, sightEnd;
public bool spotted = false;

void Update()
 {     
    RayCasting ();
    Behaviours ();
 }

void RayCasting()
{
    Debug.DrawLine (sightStart.position, sightEnd.position, Color.red);
    spotted = Physics2D.Linecast (sightStart.position, sightEnd.position, 1 << LayerMask.NameToLayer("Player"));
}

void Behaviours()
{
        if (spotted == true) {
            //Invoke("Fire", cooldownTimer);
            Fire ();
    } else if (spotted == false) {
        //CancelInvoke ();
    }
}

void Fire()
{       
        GameObject bullet = (GameObject)Instantiate (bulletPrefab);
        //GameObject bullet = objectPool.GetPooledObject (); 
        bullet.transform.position = transform.position;
        bullet.GetComponent<Rigidbody2D> ().velocity = bullet.transform.up * 14;
        Destroy (bullet, 2.0f);
}
1

1 Answers

2
votes

You need to throttle the rate at which bullets are spawned. You could base it on number of frames but that's a bad approach as fire rate will vary with game performance.

A better approach is to use a variable to track how much time must elapse before we can fire again. I'll call this "Time To Next Shot" (TTNS)

  • Decrement TTNS by the time that has elasped.
  • Check if TTNS is 0 or less
  • If so:
    • Set TTNS as appropriate for our desired rate of fire.
    • Fire a shot

Something like..

private float fireRate = 3f; // Bullets/second
private float timeToNextShot; // How much longer we have to wait.

void Fire() {       
        // Subtract the time elapsed (since the last frame) from TTNS .
        timeToNextShot -= time.deltaTime;
        
        if(timeToNextShot <= 0) {
            // Reset the timer to next shot
            timeToNextShot = 1/fireRate;
            
            //.... Your code
            GameObject bullet = (GameObject)Instantiate (bulletPrefab);
            //GameObject bullet = objectPool.GetPooledObject (); 
            bullet.transform.position = transform.position;
            bullet.GetComponent<Rigidbody2D> ().velocity = bullet.transform.up * 14;
            Destroy (bullet, 2.0f);
        }
}

This does assume that you only call Fire() once per frame (Otherwise the elapsed time will be subtracted from nextShot multiple times).

I opted to do it this way (subtracting slices from a time span) rather than defining an absolute time (wait until time.elapsedTime > x) as the resolution of elapsedTime decreases over time and that approach will result in glitches after a few hours of gameplay.