Coroutine, while, and Waitforseconds
Hello, I've a problem with my Coroutine that has made me crazy for hours today :
Here is my Coroutine
IEnumerator FireCoroutine() {
while (attacking) {
Fire ();
yield return new WaitForSeconds (cooldown);
}
}
And here is my call :
void OnTriggerEnter(Collider co) {
if (co.GetComponent<Monster>() && !attacking) {
target = co.transform;
attacking = true;
StartCoroutine ("FireCoroutine");
}
}
So I have a tower that is supposed to fire a bullet every cooldown seconds when Attacking. This tower starts attacking when an ennemy enter his range, and is supposed to stop when the ennemy leaves the range or dies.
And it works fine ! ...Until sometime, when my tower decides to become crazy and randomly fire 2, 3, 4 or more bullets at once, on the same target...
He're the full script :
using UnityEngine;
using System.Collections;
public class Tower : MonoBehaviour {
public GameObject bulletPrefab;
public float rotationSpeed = 35;
public Transform target;
public bool attacking = false;
public float cooldown = 0.3f;
/* Update called every frame
* look if our current target is destroyed
* if so, we can stop attacking
*/
void Update () {
transform.Rotate (Vector3.up * Time.deltaTime * rotationSpeed, Space.World);
if (target == null) {
StopAttack ();
}
}
/* When something enters in the zone
* if it's a monster and if tower is not already attacking
* it becomes tower's target, tower pass in attack mode and we start attack coroutine
*/
void OnTriggerEnter(Collider co) {
if (co.GetComponent<Monster>() && !attacking) {
target = co.transform;
attacking = true;
StartCoroutine ("FireCoroutine");
}
}
/*
* If the target leaves the range, we can stop attacking
*/
void OnTriggerExit(Collider co) {
if (co.transform == target) {
StopAttack ();
}
}
/*
* The Coroutine : Fire every 5 seconds
*/
IEnumerator FireCoroutine() {
while (attacking) {
Fire ();
yield return new WaitForSeconds (cooldown);
}
}
void StopAttack() {
StopCoroutine ("FireCoroutine");
attacking = false;
}
void Fire() {
GameObject g = (GameObject)Instantiate (bulletPrefab, transform.position, Quaternion.identity);
g.GetComponent<Bullet> ().target = target;
}
}
Thank you !
I wonder if this is tied to framerate. Have you tried calling StopAttacking()
from FixedUpdate()
?
Answer by Maniae · Jul 03, 2016 at 09:40 AM
Finally have decided to cope with the problem by using update() and a test with a float cooldown value (that I compare with Time.time) instead of using coroutine. I assume this is not the best way to do this but as I'm a beginner I don't want to be stopped in my little project because of this and prefer to learn more about Unity. I hope I will have to deal with Coroutines again and maybe it will allow me to understand the problem.
Thanks a lot for your help (and time) though.
Your answer
Follow this Question
Related Questions
Coroutine or While loop that you can reset/add time too? 0 Answers
Add points every five seconds 1 Answer
Weirdest coroutine crash ever 1 Answer
running a while loop until coroutine finishes 0 Answers
Coroutine not working 1 Answer