- Home /
IEnumerator not waiting before relooping.
I have an enemy who in the update fires projectiles at the player if in range every X seconds however he never waits between shots. I've checked with the print statements that the projectile is fired multiple times before the WaitForSeconds
happens. Can someone explain what I've done wrong.
if (distanceToPlayer <= attackRange)
{
aiCharControl.agent.isStopped = true;
anim.SetFloat("BlendY", 0);
//Fire or Attack
StartCoroutine(FireProjectile(target));
}
private IEnumerator FireProjectile(Transform target)
{
GameObject projectile = Instantiate(projectileToUse, projectileSpawnPoint.position, Quaternion.identity) as GameObject;
Projectile projComponent = projectile.GetComponent<Projectile>();
float projSpeed = projComponent.Speed;
Vector3 distanceToPlayer = (target.transform.position - projectileSpawnPoint.transform.position).normalized;
projectile.GetComponent<Rigidbody>().velocity = distanceToPlayer * projSpeed;
projectile.transform.LookAt(target);
projComponent.Damage = projectileDamage;
print(Time.time + " Before wait");
yield return new WaitForSeconds(timeBetweenShots);
print(Time.time + " After wait");
}
Answer by GenericToast · Sep 13, 2017 at 02:28 PM
I assume you are checking if (distanceToPlayer <= attackRange)
in an Update loop, this means StartCoroutine(FireProjectile(target));
is being called multiple times so the projectile is shot multiple times.
What you can do is have a bool canShoot
variable and change it so that the coroutine is only called when canShoot is true
if (distanceToPlayer <= attackRange)
{
aiCharControl.agent.isStopped = true;
anim.SetFloat("BlendY", 0);
//Fire or Attack
if(canShoot)
StartCoroutine(FireProjectile(target));
}
In your FireProjectile coroutine add in a line that sets canShoot to false, and set it back to true after the WaitForSeconds is finished
private IEnumerator FireProjectile(Transform target)
{
//All your previous code here
//New line of code here
canShoot = false;
print(Time.time + " Before wait");
yield return new WaitForSeconds(timeBetweenShots);
print(Time.time + " After wait");
canShoot = true;
}
Hope this helps
To clarify to the OP: you create a new coroutine over a new IEnumerator every time you call StartCoroutine(FireProjectile(target));
You have no more lines of code after your yield new WaitForSeconds()
so there is no code that would get delayed by it. All of the code in the IEnumerator is executed as soon as you start the brand new coroutine.
IEnumerators/CoRoutines don't loop (as you suggest in the title) unless you really have a loop in it.
ah thank you both, I was viewing it as a sort of loop that goes "do everything until the yield return, then waitforseconds". So it would only "reloop" after its waited for that amount of time.
Your answer
Follow this Question
Related Questions
How to make loop with call to IEnumerator actually pause? 2 Answers
WaitForSeconds Not Working 4 Answers
Problem with coroutine 2 Answers
How Return Or Restart A Coroutine When A Variable Increase? 0 Answers