How CancelInvoke () works in unity

So, I thought a lot about formulating the title of this topic, but somehow ended up with a dumb question.

What I want to do:

I want to reorganize my code so that I can replace all Invoke (string, seconds) calls in unity with my own (Routine) IEnumerator WaitAndExecute(float time, Action callback) , which waits for seconds of โ€œtimeโ€ and makes a โ€œcallbackโ€.

Cause. I do not want to pass methods as strings, as this makes it difficult to find references in the IDE.

Problem: My CancelInvoke () does not work with methods that were executed without Invoke ().

So, I want to know how unity preserves traces of things and references to called methods so that they can be canceled later.

+5
source share
2 answers

The following is just an assumption.

Most likely when you call Invoke (string, float); Unity adds a dictionary of type string, object. This allows you to run any signature. On the other hand, a more general indicator makes less accuracy.

The string is probably used to reflect the object to see if this method can be added:

 MethodInfo mi = this.GetType().GetMethod(methodName); if(mi != null){ // Create Delegate // Add to dictionary or other collection } 

Each frame iterates through all the records and starts them if the time is done. Then deletes the record.

When you call CancelInvoke (string); it checks if the record exists and deletes it.

If you want to deal with coroutine coroutine, you can use:

 IEnumerator coroutine = null; IEnumerator MyCoroutine(){ yield return null; } void Start(){ coroutine = MyCoroutine(); StartCoroutine(coroutine); StopCoroutine(coroutine); coroutine = null; } 

Note that the internal functioning of this template is most likely similar to Invoke with an IEnumerator collection awaiting execution.

+1
source

This is what I understood from your question: you have some calls and some coroutines in your code.

Earlier, before refactoring, you had to call CancelInvoke (), but at the moment you should connect any CancelInvoke () with StopAllCoroutines () on any MonoBehaviour.

It should also be noted that your method

 IEnumerator WaitAndExecute(float time, Action callback) 

not very good, you also need to pass MonoBehaviour to start coroutine exactly on the object that wants to start Callback. eg:

 public class Player : MonoBehaviour { void Start() { Utils.WaitAndExecute(this , 5, callback); } public void callback() { // blah blah blah } } public class Utils { public void WaitAndExecute(MonoBehaviour objectToRun , float time, Action callback) { // ... objectToRun.StartCoroutine(...); // ... } } 

This way you can easily stop coroutines inside the script player:

 StopAllCoroutines(); 
+1
source

All Articles