If you have a gameobject with a script running a current InvokeRepeating method and you set the gameobject to inactive, then back to to active, will the InvokeRepeating loop resume or will it have been cancelled outright?
The answer is that the object will continue to execute the InvokeRepeating().
Deactivating a game object does not stop the InvokeRepeating().
To deactivate the whole game object: gameObject.SetActive(false)
Deactiving just the script component itself does not stop the InvokeRepeating().
to deactivate just the script component: this.enabled = false
BUT NOTE THAT COROUTINES ARE DIFFERENT
Note however that ordinary coroutines, do indeed get stopped, when you deactivate the game object. However if you deactivate only script itself then the coroutine does keep going.
For InvokeRepeating…
1) disable whole game object - InvokeRepeating does not stop
2) disable just the script component - InvokeRepeating does not stop
For coroutines…
3) disable whole game object - coroutine DOES stop
4) disable just the script component - coroutine does not stop
In all four cases, the repeat is “eliminated”, it is NOT paused. If you again SetActive(true), in all four cases, the repeat does NOT continue where it left off.
.
When I have questions like this one, I just test it:
private var i = 0;
function Start() {
InvokeRepeating("CountUp", 0.0, 0.5);
Invoke("Disable", 3.0);
}
function Disable() {
gameObject.SetActive(false);
}
function CountUp() {
i = i+1;
Debug.Log("i=" + i);
}
to test all four situations, simply do this,
using UnityEngine;
using System.Collections;
public class CoTeste:MonoBehaviour
{
void Start ()
{
InvokeRepeating("_everySecondInvoked", 1.1f, 1.1f);
StartCoroutine(_everySecondCoroutine());
}
private void _everySecondInvoked()
{
Debug.Log("this I.R. appears every second "
+ Random.Range(1111111,9999999) );
}
private IEnumerator _everySecondCoroutine()
{
while(true)
{
Debug.Log(" this coroutine appears every second "
+ Random.Range(1111111,9999999) );
yield return new WaitForSeconds(Random.Range(1.1f,1.2f));
}
yield break;
}
}
Run the project, and simply in the editor try disabling just the script (un-tick the box in the inspector).
note that both the coroutine and the invokeRepating simply keep going forever.
Start over, and disable the whole game object (un-tick the box in the inspector).
note that the InvokeRepeating keeps going forever, BUT, the coroutine DOES STOP.
Simply use OnDisable()…
, or one of the similar routines, if you want something “custom” to happen when a game object (or just the script) is disabled.
OnDisable and the similar routines
This is completely commonplace. Indeed,
… You almost always use OnDisable() …
.
when you launch a coroutine or invokeRepeating - unless it’s a really trivial situation and it doesn’t matter.
This post is very old at this point, however I had some interesting thoughts that I wanted to share on this subject for any future viewers.
-I always like to think about the enabled property of a component as something closer to “allowUnityLifeCycleEvents” rather than enabled. An interesting example outside of the coroutine or invokerepeat case would be the case where I have (enabled) scriptA that references a disabled scriptB reference. ScriptA can invoke public facing members of scriptB despite the fact that scriptB is disabled. “Enabled” does not mean “nothing will function and everything gracefully pauses”… instead it only stops the built in unity lifecycle events from being triggered (Awake, Start, Update, LateUpdate, ect…). A good test/sandbox could be this:
public class TestClassA : MonoBehaviour
{
private TestClassB m_classBReference = null;
public void Update()
{
m_classBReference.Update();
}
}
public class TestClassB : MonoBehaviour
{
public void Update()
{
Debug.Log("I am active!");
}
}
- Create a new scene, create a gameobject and place a “TestClassA” component on it
- Create another gameobject and place a “TestClassB” component on it
- Drag and drop the gameobject with your “TestClassB” component on it onto the “Class B Reference” property exposed in the inspector for the gameobject with the TestClassA component
- Run the scene
You should see the logs being printed out at first… now try disabling combinations of both scripts. If you disable TestClassB and leave TestClassA enabled, you should still see the logs. Play around with this and become comfortable with how it works.
Now in regard to the “I think my script should disable everything” mentality… Unity will not do this for you, but you have powerful tools and frameworks at your fingertips to accomplish something that you are comfortable with. You could create your own class to use instead of MonoBehaviour (pardon my awful programmer class name) named something like “DisableableBehaviour”. This class can inherit from MonoBehaviour… then all you need to do is framework how you want it to work… for example: You could expose your own special function for starting coroutines or invokerepeat calls and have the class track them so that the class can cancel them on disable and restart them on enable. I’m certain there are tons of ways of doing this… just know that unity doesn’t need to do it all. Coroutines and invoke calls are very useful in the fact that they do span across frames regardless of enable or disable states, but you can always code up something that works for you
Not sure if this was an option in Unity when this was posted - but using Cancellnvoke() on any Monobehaviour script stops all invoke calls