user15249423
user15249423

Reputation:

While loop timer with a bool that doesnt work Unity 3D

Using c#, im trying to fire a bullet every 3 seconds, so heres my workflow:

  1. fire button is pressed
  2. only fire if bool fireAgain is true
  3. set bool fireAgain = false
  4. start timer
  5. timer finished = bool fireAgain = true

When debugging it seems to all work properly, but when I test it, Im still able to shoot like 10 bullets a second. So somehow it just doesnt care about the bool FireAgain being false and shoots anyway even if according to debug bool fireAgain is false at that moment.

 public void Update()
    {
    //If  LEFT MouseButton is pressed, cast yer spells.
            if (fireAgain == true && Input.GetMouseButtonDown(0)) 
    {   
        StartCoroutine("LoopRotation");
        fireAgain = false;
        Debug.Log(fireAgain);
        Debug.Log("1 should be FALSE");
    }
        while (fireAgain == false && timer < bulletTime)
    {
        fireAgain = false;
        timer += Time.deltaTime;
        Debug.Log(timer);
        Debug.Log(bulletTime);
        Debug.Log(fireAgain);
        Debug.Log("2");
    } if (timer >= bulletTime)
    {
        fireAgain = true;
        timer = 0;
        //Debug.Log("Timer is finished");
        //Debug.Log(timer);
        Debug.Log(fireAgain);
        Debug.Log("3 should be true");
        

And here is the code for the Coroutine:

IEnumerator LoopRotation()
{
    pivot.transform.Rotate(triggerAngle,0,0);
        
        GameObject bullet = ObjectPooler.SharedInstance.GetPooledObject(); 
        if (bullet != null) {
                bullet.transform.position = SSpawn.transform.position;
                bullet.transform.rotation = SSpawn.transform.rotation;
                bullet.SetActive(true);
         }

    yield return new WaitForSeconds(.1f);
            pivot.transform.rotation = Quaternion.Slerp(transform.rotation, originalRotationValue, Time.deltaTime * rotationResetSpeed); 
    StopCoroutine("LoopRotation");
}

Enumerator LoopRotation was originally just to pivot the weapon a few degrees forwards and then backwards so it looks like a wack when you cast a spell, but now its also the shoot function, as it creates bullets.

Upvotes: 1

Views: 875

Answers (1)

derHugo
derHugo

Reputation: 90580

You have a while loop within Update => this loop will completely run in one single frame => "immediately" will increase the timer until it is big enough => "immediately" will set your bool flag to true again!

What you rather would do is e.g.

public void Update()
{
    //If  LEFT MouseButton is pressed, cast yer spells.
    if (fireAgain && Input.GetMouseButtonDown(0)) 
    {   
        StartCoroutine(LoopRotation());
        fireAgain = false;
        timer = 0;
        Debug.Log(fireAgain);
        Debug.Log("1 should be FALSE");
    }
    else if(timer < bulletTime)
    {
        // Only increase this ONCE per frame
        timer += Time.deltaTime;
        Debug.Log(timer);
        Debug.Log(bulletTime);
        Debug.Log(fireAgain);
        Debug.Log("2");

        if(timer >= bulletTime)
        {
            fireAgain = true;
            timer = 0;
            //Debug.Log("Timer is finished");
            //Debug.Log(timer);
            Debug.Log(fireAgain);
            Debug.Log("3 should be true");
        }
    }
}

As alternative you could use Invoke and skip the timer in Update completely:

public void Update()
{
    //If  LEFT MouseButton is pressed, cast yer spells.
    if (fireAgain && Input.GetMouseButtonDown(0)) 
    {   
        StartCoroutine(LoopRotation());
        fireAgain = false;
        Invoke (nameof(AllowFireAgain), bulletTme);
    }
}

private void AllowFireAgain()
{
    fireAgain = true;
}

Note that your Coroutine doesn't make much sense to me. You are only rotating exactly once and only a really small amount.

The StopCoroutine in the end is unnecessary.


Also note: for debugging fine but later you should avoid to have Debug.Log running every frame in a built application. Even though the user doesn't see it the log is still created into the player log file and causes quite an amount of overhead.

Upvotes: 2

Related Questions