Usando C#, intento disparar una bala cada 3 segundos, así que aquí está mi flujo de trabajo:
Cuando se depura, parece que todo funciona correctamente, pero cuando lo pruebo, todavía puedo disparar como 10 balas por segundo. Entonces, de alguna manera, simplemente no le importa que bool FireAgain sea falso y dispara de todos modos, incluso si, de acuerdo con la depuración, bool fireAgain es falso en ese momento.
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");Y aquí está el código para 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 originalmente solo giraba el arma unos pocos grados hacia adelante y luego hacia atrás para que pareciera un loco cuando lanzas un hechizo, pero ahora también es la función de disparar, ya que crea balas.
Tiene un ciclo while dentro de Update => este ciclo se ejecutará completamente en un solo cuadro => "inmediatamente" aumentará el timer hasta que sea lo suficientemente grande => "inmediatamente" establecerá su indicador bool en true nuevamente.
Lo que preferirías hacer es, por ejemplo,
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"); } } } Como alternativa, puede usar Invoke y omitir el temporizador en Update por completo:
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; }Tenga en cuenta que su rutina no tiene mucho sentido para mí. Solo está girando exactamente una vez y solo una cantidad muy pequeña.
El StopCoroutine al final es innecesario.
También tenga en cuenta: para la depuración correcta, pero luego debe evitar que Debug.Log ejecute cada cuadro en una aplicación creada. Aunque el usuario no lo ve, el registro aún se crea en el archivo de registro del reproductor y causa una gran sobrecarga.