MonoBehaviour.Invoke
Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.
Submission failed
For some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.
Declaration
Description
Invokes the method methodName in time seconds.
If time is set to 0 and Invoke is called before the first frame update, the method is invoked at the next Update cycle before MonoBehaviour.Update. In this case, it’s better to call the function directly.
Note: Setting time to negative values is identical to setting it to 0.
In other cases, the order of execution of the method depends on the timing of the invocation.
If you need to pass parameters to your method, consider using Coroutine instead. Coroutines also provide better performance.
Unity: A better way to Invoke
Since this article has been released, a lot as changed with Unity and my own knowledge. Therefore I’ve created an updated version of this post, which you can find here.
Unity provides developers with an easy solution to calling a method after a delay. This method is called Invoke . It has a pretty obvious benefit:
- It’s easy to understand and use
But unfortunately, there are far more drawbacks which make this method a candidate for obsoletion.
- It relies on string dependencies, and therefore is prone to typos which may not be caught until runtime
- It does not support parametered methods
- It relies on a distinct method to exist
- It uses reflection to find the method you provide
- You can’t return a value
The problem
Consider the following example:
Let’s go through some of the problems listed above:
- Invoke accepts a string for the method name. This is called a string dependency. String dependencies mean the actual name of the method in code, and the string, are unrelated to each other making refactoring extremely difficult. It is also prone to typos which you will not encounter until you run the game.
- The ChangeColorAfterDelay method cannot accept any parameters. Its logic is fixed, which means if we wanted to change to a different color, we’d have to create another method – creating duplicate code.
- It relies on a method existing in the first place. This does not always make sense. It means that other methods in our class can access this method and that may or may not be what we want to allow. It means we cannot have a single part of the code fire-once-and-forget after a delay.
- Most developers know that reflection is slow. Fetching a method by name is akin to finding an object by its tag. It has to search every method name until it finds a match. This is horribly inefficient.
The only saving grace…
One of these problems can be averted pretty easily. But only one. We can use the nameof operator which will convert a symbol name to a string at compile time. This means if we decide to rename our method using quick-refactor tools, all instances of that name will be changed.
However, this does not change the fact that we are passing a string – which means reflection is being used internally. Besides, we still have the outliers: No parametered methods, no inline invocation, no return values.
A note on coroutines
We have, at our disposal, Unity’s implementation of coroutines. While this is a commonly suggested solution, and does entirely solve the problem of reflection, it still relies on another method existing to run the action – which may or may not be your desired intention.
Of course, you can also make Start itself a coroutine:
That’s seemingly innocuous, right?. “What’s the problem with this?”, I hear you ask. Well, while you can make Start and other fire-once methods a coroutine, you cannot make Update a coroutine:
Which means if you are trying to delay an action from Update , you would still need to create a separate method to act as the coroutine. If you don’t actually need the action to be in a separate method, then this is not good enough.
The solution: Don’t Invoke , await !
In recent times, .NET has introduced the concept of asynchronous programming which is similar to (but often misconstrued as) multi-threading. I’m not going to go into detail about how async / await works – you can read more about that here – but suffice to say that Unity has its own SynchronizationContext which allows async code to run quite smoothly within the engine. We simply have to mark out method as async , and await a Delay :
Yes, this also works with the Update method. In fact, it works with all of the built-in Unity methods! We could just as easily do this:
This also has another added benefit, such that if we wanted to create a separate method for this task, we could pass arguments:
What about InvokeRepeating ?
InvokeRepeating is another common one I see people use. This has all the same problems as Invoke , so I won’t be covering those again.
The alternative is: You decide. There are a couple of ways you can achieve this. I will briefly cover two options:
A simple timer in Update
All we’re doing is checking if the time at which the last change was made, exceeded 2 seconds. If it does, go ahead and perform the action – resetting the last time that the change happened. This works, and is actually a very common solution. Go ahead use this if it satisfies your needs.
Coroutines
Yes, I’m aware. I took a shit on coroutines a few moments ago. But like I said, if it makes sense to delegate the functionality to its own method – this is the better solution.
Unity MonoBehaviour.Invoke with C# examples
Hello programmers, In this article, you will learn about Unity MonoBehaviour.Invoke with C# examples.
Before we get started with the building process, we need to know a few concepts. Let’s first discuss them one by one.
MonoBehaviour.Invoke
The Invoke functions enable you to call a function after some specified time delay.
This allows us to build a helpful system to call methods, that is time sensitive.
Syntax:
public void Invoke(string methodName, float time);
Example:
- Attach the InvokeScript to the GameObject obstacle.
- In the Invoke Script, we can see a public GameObject named obstacle.
- We also have a method named SpawnObstacle.
- The SpawnObstacle method will simply Instantiate the obstacle object.
- As we can see in the start method, we call the Invoke function.
- Invoke function takes two parameters.
- The first parameter of Invoke is the name of the function that you want to execute.
- The second parameter of Invoke is the time delay after which you want it to happen.
If we want to call Invoke method repeatedly:
To call Invoke method repeatedly can be done easily with one line of code.
Syntax:
public void InvokeRepeating(string methodName, float time, float repeatTime );
Simple Timer in Unity — Part 1
Let's look at simple ways to create timer in Unity with Invoke() and Coroutine in the first part of this multipart series.
Raju Nepali
When we say timer, we generally think of a time which increases from 0 to a certain time. It can be a countdown or a continuous timer that increases. It doesn’t matter what the case is, but you get the meaning when anyone says timer.
A timer’s usage is essential in most cases where you need to wait for a certain time. In most of the games, you might need to wait for multiple cases and for each case, you will need to create a different timer. Handling the timer may be easier if the project is small, but it will become harder as the project grows. It also makes code longer than necessary.
Ways to Run Timer in Unity
In Unity, you can run the timer using the following ways:
- Invoke
- Coroutine
- Update
- Async Await plugin
In this article, we’ll be using timers with Invoke() and Coroutine
1. Timer with Invoke() : Simple Timer
Invoke() is a method provided by MonoBehaviour in Unity. It helps you run a method after a certain time interval. The method must not have any parameter and must be invoked with a time greater than 0 . Using a 0-time interval is the same as not waiting. So, just calling the method is faster instead of using Invoke() .
The syntax of Invoke() is:
You can use any one of the ways to use Invoke() as given above.
By calling the invoke in loop format, you will be able to run the method continuously, until you manually cancel it by using CancelInvoke(nameof(NameOfMethod)) .
Creating a Timer Method Using Invoke()
Step 1: First, create a number variable which increases each second.
Timer Representing Integer
Step 2: Create a method to increase the _timer in 1-second intervals.
Method to Increase the Timer
After calling the StartTimer() , your timer will increase from 0 until you cancelInvoke() to stop the loop of the timer invoked.
You can create a new method with the following code to stop this timer.
Timer Representing Integer
This is just a normal timer which starts from 0 and increases until you cancel it. We can provide a time-out value so that timer increases up to the given specific time and stops by itself but let’s not do that with Invoke . It is not good to use Invoke for this type of work. It can be done easily using Coroutine , and we will do so later in the article.
The full code of this is given below.
Full Code for TimerWithInvoke
2. Timer with Coroutine
Coroutine is one of the functions provided by Monobehaviour to use when we need to apply the waiting process in the game. As the coroutine runs in separate thread from the normal running code in Unity, we can run it without any problem to keep the record of the timer we need without affecting the running code. You can also wait until the timeout is called and continue your code.
The timer using coroutine is also very easy. We just need to run a loop which increases the timer value until we stop it or give a time-out value. When using coroutine method, don’t forget to add IEnumerator as the return value for the method. Make sure that the starting of coroutine is done in the following way.
Starting the Coroutine Method
Here, _timerCoroutine is a global IEnumerator holding the IEnumerator of the StartTimer() method.
The reason for using separate IEnumerator to hold the running IEnumerator of the coroutine is because stopping this coroutine is effective if we apply StopCoroutine to the running IEnumerator rather than the method directly.
The stopping method for this coroutine looks like this.
Stopping the Coroutine method
Now improvise the StartTimer() we mentioned above in Invoke() section for coroutine use, as shown below.
Timer with Coroutine
Give a total time you want the timer to run in the parameter and run a loop until the given time and a simple timer is completed with coroutine .
Adding Callback When Timer is Up
You can add an Action to be triggered when the timer is up. It helps the developer continue the work that has to be run when the timer is up. So let’s just add a little change to the existing code and create a timer with callback in the above code.
First, save the action provided at the start of the timer to the OnTimeOut action.
Addition of Action Callback OnTimeOut
Then just trigger the action when the timer is up.
You can directly add the callback action in the parameter and trigger it when the timer is up. You can also create a global action that will hold the provided action in the parameter and be triggered when the timer is up.
The process is up to you, but for now, we will use a global action to hold the action to be triggered on time up, as mentioned in the above code.
Timeout Action Trigger Added
Lastly, when stopping the timerCoroutine , remove the assigned action to our global action OnTimeOut .
Stopping the Coroutine method
Here is the full code for TimerwithCoroutine .
Full Code for TimerWithCoroutine
To Summarise,
we have just finished creating a simple timer in two ways; Invoke and Coroutine in this article. The other two ways, update and async await plugin will be described in the second part of this article.
Confusing Functions in Python
In this blog, we will cover topics such as default argument values, mutable default arguments, and variable scoping, and will provide examples and explanations to help demystify these concepts.
Creating Real-Time Magic Beams Visual Effects: Part 2
The beam part is created using a UV scrolling shader that is later modified in the particle system. The anticipation parts of the effect will be done in the unity particle system with the help of some textures created in GIMP and a simple mesh.
Creating a Text-Based Dialogue System in Unity
Easily learn how to develop a text-based dialogue system in Unity with this blog.