WaitForSeconds
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.
Description
Suspends the coroutine execution for the given amount of seconds using scaled time.
The real time suspended is equal to the given time divided by Time.timeScale. See WaitForSecondsRealtime if you wish to wait using unscaled time. WaitForSeconds can only be used with a yield statement in coroutines.
There are some factors which can mean the actual amount of time waited does not precisely match the amount of time specified:
1. Start waiting at the end of the current frame. If you start WaitForSeconds with duration ‘t’ in a long frame (for example, one which has a long operation which blocks the main thread such as some synchronous loading), the coroutine will return ‘t’ seconds after the end of the frame, not ‘t’ seconds after it was called.
2. Allow the coroutine to resume on the first frame after ‘t’ seconds has passed, not exactly after ‘t’ seconds has passed.
How to add time delay in Unity C#
So I’m trying to make a camera zoom in, but Thread.Sleep doesn’t work. Here is the code:
The error code is this:
2 Answers 2
You are getting this error message because you are missing a line that accesses the API for this. Simply add using System.Threading; at the top of your script. This will access the API for it. Or use a coroutine, which won’t freeze the entire game as a whole and is a much better alternative, as DMGregory suggested.
An important thing to understand about Unity is that the MonoBehaviour message methods like Start() and Update() are called on the main thread (ie. single-threaded). So if you stall one of them by hitting a long-running loop or sleeping the thread, you cause the entire game to hang.
So, if you want to add a delay, it needs to be by yield ing control back to the engine temporarily — so it can continue running other update functions, accepting input, rendering frames, etc. — until you are ready to resume your work.
You must log in to answer this question.
-
The Overflow Blog
Linked
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.3.11.43300
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Как сделать задержку выполнения кода в Unity C#?
не рекомендую делать WaitForSeconds в Update потому что по сути такой код будет начинать каждый тик (Update вызывается 60 вроде бы раз в секунду) новый интервал задержки, и сам Update может встать (или чтото еще в таком духе, надо тестить, вообщем баг явный)
на самом деле такой код может рабоатть, но только для быстрых корутин, не для ожидания 5 сек
аналогично из Start можно запускать корутину с ожиданием
лучше запустить корутину из Start() — пример же в доке есть
How to delay a function in Unity
Even if you’re new to Unity, calling a function can be very straightforward.
Simply call the function using its name, and it will be triggered immediately.
However, what if you don’t want to do something immediately?
What if you want to do something in one second’s time?
Or every half a second?
Or every minute?
There are a lot of different ways you could delay a function in Unity and, while they are all, typically, very straightforward, it can sometimes be tricky to know which method you should use.
In this article, you’ll learn the different ways to delay a function by an amount of time, so that you can choose the method that’s right for your project.
So, how can you delay a function in Unity?
How to delay a function in Unity
Normally, the code that you write will be executed line by line, in order.
Some functions will be called before others, like Unity’s event functions, for example, such as Update, and On Enable, which are called in a specific order.
And some events will be called before the same events on other scripts, in a, seemingly, random order, but one that can be controlled using the Script Execution Order Settings.
The Script Execution Order settings in Unity allow you to modify when a script is executed, relative to its Default Time.
However, even though functions and code are executed in order, most of your code will generally happen during the frame it’s called in.
Meaning that, if you want to delay a block of code in your game, or call a function in a few seconds’ time, you’ll need to find a way to delay the execution of that method.
Generally speaking, there are three main ways to delay a function in Unity:
- You can call the function using the Invoke method, which allows you to schedule a function to be called in an amount of time,
- You can yield the execution of a block of code using a Coroutine,
- Or you can measure a time delay manually, using a Script.
How to use Invoke to delay a function
The purpose of the Invoke function is to call a method with a delay.
It works by passing in a String parameter, which is the name of the function that you want to call, and a Float delay, which is how long you want to wait before the function is triggered.
Like this:
Invoke works on the script you call it on, meaning that you can use it to trigger a function in the same script or to trigger a function on a different script that you have a reference to.
Like this:
And, because Invoke is a function of the script that holds the method, not the script triggering it, its possible to call private functions on other scripts using Invoke.
How to cancel Invoke
You can cancel an already triggered Invoke function, before the method is executed, by using Cancel Invoke.
Like this:
Which will cancel any invoked function called by the class with the matching string name.
Or, Like this:
Which will cancel all invoked functions on the class, regardless of what they’re called.
While Invoke can be very convenient it does have a couple of drawbacks.
For example, because the function is triggered by a string, it’s possible to break the connection if its name is ever changed.
What’s more, a method triggered using Invoke can’t accept parameters.
Meaning that, if you want to delay a function, but also pass data into it, you might want to consider using a Coroutine instead.
How to use a Coroutine to delay a function
Coroutines split functionality over a number of frames.
Meaning that while, normally, an entire function is executed during one frame, when using a Coroutine, it’s possible to break it up into different steps using Yield Statements.
Yield statements allow you to pause the execution of a block of code until the next frame, until something else happens or until an amount of time has passed.
For example, it’s possible to yield for an amount of time using the Wait for Seconds class, like this:
While Coroutines can be extremely useful for splitting up logic between frames, they’re not quite as convenient as using Invoke.
What’s more, while they are, generally, very efficient, Coroutines do create a small amount of Garbage. Once when they’re first started and, depending on how you do it, again whenever they are suspended.
In which case, if all you want to do is delay something by a couple of seconds, you may find it easier to simply measure the delay yourself, using a Script.
How to delay code using a Script
In Unity, it’s possible to measure time by adding up each frame’s Delta Time, which is the amount of time, in seconds, that it took to process the previous frame, allowing you to compare the amount of time that’s currently elapsed to a required delay value.
Like this:
Then, if enough time has passed, the function will be called.
This method works because the timer is continuously checking to see if it’s time to do something or not.
However, like this, the script will endlessly trigger the function as soon as the required amount of time has come and gone.
Meaning that, to prevent the function from being called more than once, you’ll need to, either, wrap the time code in an if condition…
Like this:
Or, if you only need the script to do something once, turn it off as soon as you’re done with it.
Like this:
This method is simple, doesn’t create any garbage, and allows you to pass in parameters to the method you call.
Its drawback is that, because Update is called every frame, you’ll need to check every frame if it’s time to do something.
Even if you only do it once.
But what if you don’t want to do something just once?
What if you want to do something repeatedly, every second?
How to trigger a function repeatedly, every second, in Unity
In Unity, there will often be times when you want to trigger a function repeatedly, such as every second, or every fraction of a second.
The method of calling a function regularly like this is similar to the process of delaying a function for an amount of time, except that, instead of doing it just once, you’ll be triggering the function at timed intervals, over and over again.
In which case, because you no longer need to worry about finding a way to disable the process once it’s performed its delayed function, the Script Method of using a timer to measure a delay manually can be ideal for triggering a function at regular intervals.
How to trigger a function at regular intervals (using a Timer Script)
Triggering a function regularly using a timer in a script works in much the same way as delaying a method.
First, you’ll need to add up each frame’s delta time in Update and then compare it against the delay duration that you want.
The difference is, that, instead of disabling the script or turning off the timer when you’re finished, you’ll need to reset it instead, so that it can fire with a delay again.
Generally, the best way to reset a timer so that it triggers at regular intervals is by subtracting the interval duration you want from the elapsed time.
Like this:
But why do it this way?
Why not just reset the timer to zero?
Subtracting the time interval from the elapsed time accounts for any excess time that may have passed since the timer became larger than the required delay.
This works because, when the timer becomes due, it’s almost always going to be the case that the amount of time that passed during the frame was more than the amount required to reach the interval duration.
Resetting the timer to Zero disregards excess time that may have elapsed between reaching the interval time and actually resetting it.
Subtracting the delay from the time elapsed saves this extra time, keeping the interval duration as accurate as possible.
While simply resetting the timer to zero can cause the timer to be triggered a frame later than it would have done, as excess time, that has already passed, is written off and ignored, causing an inconsistent stuttering effect between the intervals.
For long durations, this isn’t noticeable at all, as the timer will only be out by a single frame each time, if it’s out of time at all.
However, for short, rapidly triggered functions, the effect can be much more noticeable, particularly if you’re triggering a sound effect that’s supposed to fire at fixed intervals.
How to create global time events with a Master Clock script
If you want multiple different scripts to respond to the same timing events then a good general approach is to manage time in one place, and then have other scripts respond to that script as required.
For example, if you want other scripts to respond to time that’s running out, or if you want to create a kind of day / night cycle, where things happen in your game at particular times, then it doesn’t make sense for each script to be measuring time in isolation.
Instead, you could use a simple Master Clock script to measure time and raise public Events whenever something needs to happen.
Like this:
Importantly, this script only tracks one time value, interpreting it differently to achieve different interval durations, avoiding the possibility that multiple, independent, timers could fall out of sync with each other.
The subtraction method allows you to create relatively accurate timed intervals using a manual timer.
However, it’s also possible to trigger functions repeatedly, without measuring time yourself, by using Invoke Repeating.
How to trigger a function regularly (using Invoke Repeating)
Invoke Repeating works in the same way as Invoke, which uses a String to identify a function by name, and a Float to specify how long to wait before triggering it.
The difference is that Invoke Repeating will then, after the initial delay, repeat the function at a set interval.
Like this:
Invoke Repeating is as accurate as the time subtraction method, meaning that if you want to repeat the same function at regular intervals, both methods will work as well as each other.
However, the drawback is, that, just like when using Invoke, because it’s called using a string, you won’t be able to pass in any parameters when you use it.
Now it’s your turn
Now I want to hear from you.
How are you delaying the execution of logic in your game?
Are you using Invoke? Or are you measuring time manually?
And what have you learned about staging logic in Unity that you know other people will find helpful?
Whatever it is, let me know by leaving a comment.
by John Leonard French
Game audio professional and a keen amateur developer.
Get Game Development Tips, Straight to Your inbox
Get helpful tips & tricks and master game development basics the easy way, with deep-dive tutorials and guides.
My favourite time-saving Unity assets
Rewired (the best input management system)
Rewired is an input management asset that extends Unity’s default input system, the Input Manager, adding much needed improvements and support for modern devices. Put simply, it’s much more advanced than the default Input Manager and more reliable than Unity’s new Input System. When I tested both systems, I found Rewired to be surprisingly easy to use and fully featured, so I can understand why everyone loves it.
DOTween Pro (should be built into Unity)
An asset so useful, it should already be built into Unity. Except it’s not. DOTween Pro is an animation and timing tool that allows you to animate anything in Unity. You can move, fade, scale, rotate without writing Coroutines or Lerp functions.
Easy Save (there’s no reason not to use it)
Easy Save makes managing game saves and file serialization extremely easy in Unity. So much so that, for the time it would take to build a save system, vs the cost of buying Easy Save, I don’t recommend making your own save system since Easy Save already exists.
Image Attribution
Comments
Use the nameof function to get the string name of the method you want to pass into Invoke/InvokeRepeating. This prevents issues with renaming and misspelling as well as removing the warning of a method being unused.
Great tip! thank you.
I actually found out that the Rider IDE suggest this syntax (to use NameOf) if you do it in the way the article originally suggests.
Just a small example of many that Rider will continue to make you a better Unity programmer if you let it
I use each of these options, but mostly a simple script, though I don’t use Time.deltaTime, only Time.time. I’d love to try the first one.
As for the coroutine, it’s a good idea to declare WaitForSeconds/WaitUntil etc. as a regular variable and with a separate variable for the amount of time. Something like
float time;
WaitForSeconds myTimer = new WaitForSeconds(time);
and then in Coroutine:
yield return myTimer;
Normally, each coroutine launch forces a new WaitForSeconds declaration. If declared beforehand, it will only read the value.
Thanks for the tip, declaring it in advance avoids creating garbage too! Since WaitForSeconds is a class.
There’s one thing I don’t understand.
In my opinion, despite Coroutines do create a small amount of Garbage , using Coroutines is still more efficient and concise than using update.
Cause If you use Update,Unity will call it in every frame.
And u alloc some new variables(timer,delay),they will also be recycled by GarbageCollector.
I guess it depends on the type of variable. new reference variables in functions are stored on the heap, so they can create garbage, but value-type variables are stored on the stack, so they don’t. If you declared a new class in Update, then it’d cause garbage every frame, however I believe in a coroutine, so long as it wasn’t inside the part of coroutine that gets suspended, such as a while loop, then it may not do. However, this isn’t something that I’ve specifically tested. Personally, I don’t think there’s a lot of difference in performance, since the part of the coroutine that yields is just a different event function, like Update, so it still gets called every frame, it’s just easier to stop calling it when you’re finished with it. Hope that helps.
Leave a Comment Cancel reply
Welcome to my blog
I’m John, a professional game composer and audio designer. I’m also a keen amateur developer and love learning how to make games. More about me
Latest Posts
- Addressable Assets in Unity
- Async in Unity (better or worse than coroutines?)
- State Machines in Unity (how and when to use them)
- How to use Arrays in Unity
- How to delay a function in Unity
Thanks for Your Support
Some of my posts include affiliate links, meaning I may earn a commission on purchases you make, at no cost to you, which supports my blog.