- Home /
Reset-Cancel Coroutine in Unity
two objects 1 and 2; in 2. object I am calling a public function from the 1. object. however, in the 2. object I have a coroutine which should cancel when I call this public function I mentioned above.
I tried using StopCoroutine but it just pauses it. So i use a reload variable to check if the coroutine should work or not. is there any better way to do this?
OBJECT 1
private bool fire = true, reload = false;
//In the update lets say i call the coroutine "Reset_Fire" and set the "fire" to false
public void Reset_Attack()
{
fire = true;
reload = false;
Debug.Log("MO - 1");
//when this function is called.
//without the "reload" bool, it prints two "CO - 2" strings from "Reset_Fire"
//with the "reload" bool it prints "CO - 2" once but it shouldnt ever print it.
}
IEnumerator Reset_Fire()
{
yield return new WaitForSeconds(1f);
if (reload == true)
{
Debug.Log("CO - 2");
fire = true;
reload = false;
}
}
OBJECT 2
void Start()
{
player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
}
private void Take_Damage(int dmg)
{
hp -= dmg;
player.Reset_Attack();
if(hp <= 0)
{
Destroy(gameObject);
}
}
//the object tagged as "Light" isnt the 1. object or its child!!!
private void OnTriggerEnter2D(Collider2D col)
{
if(col.tag == "Light" && hurt == false)
{
hurt = true;
Take_Damage(1);
StartCoroutine(Reset_Hurt());
}
}
IEnumerator Reset_Hurt()
{
yield return new WaitForSeconds(0.5f);
hurt = false;
}
Answer by BBIT-SOLUTIONS · Mar 08, 2020 at 08:13 PM
Maybe the problem is, that you call the Reset_Fire()
Coroutine inside Update()
, like you described in the comment of object1. And if you set reload
back to true anywhere in the Update()
(which is probably called more than once in a second) and then wait for one second, you could have multiple running Coroutines. Not sure, but i guess you could have a race condition here.
Maybe you can try to ensure, that the Reset_Fire
coroutine is running only once at the same time, by using a Coroutine variable for it and setting it to null, when the current one is done.
Or you could ensure, that it is really only started once immediately after a shot by a currentlyShooting
flag/bool or similar.
For a better analysis it would be also maybe helpful to see your Update()
method in object 1
Yeah, after I had a good night's sleep I noticed the problem was using "getaxis" to get the input. changed it with "getkeydown" and it works now. Even though it is fixed do you know any better way to reset the coroutine ins$$anonymous$$d of using bool variables as I do in the code above?
You could maybe also ensure that the coroutine is just running exactly once, by checking if it is null. Notice, that even an already stopped Coroutine is not null. So this should work, when you additionally set it to null after you have actually stopped it.
Something like this:
Coroutine fireReset;
private void Take_Damage(int dmg){
if(fireReset != null){
StopCoroutine(fireReset);
fireReset = null;
}
fireReset = StartCoroutine(Reset_Fire());
}
Your answer
