dude absolutely I don’t want to wait for 200 sec
I think you don’t play any game?!
I said I want to upgrade an item so a player needs to know the left time
3:20
3:19
3:18
…
00:00
so I don’t want to use yield return new WaitForSeconds(200)!!!
What do you mean about realtime ? receive time server every sec?!
Lets say server will send to client command “Item XYZ will be unblocked in 200 seconds”. Then you just store it somewhere
var itemXyzUnblockTime = Time.realtimeSinceStartup + 200;
and now you can do any calculations you need. For example if you need to know how much time is left to unblock you just calculate it like this
Debug.Log(itemXyzUnblockTime - Time.realtimeSinceStartup);
There is no need to use WaitForSeconds. Or at least use WaitForSecondsRealtime.
Btw, I am sure KelsoMRK plays some games, he gave you good advice, you just didn’t get it.
yes I am kidding but he said use yield return new waitforSecond(200)
Thank you all. Best regards
No I didn’t. I said use it for what you were trying to do in that example. You never adequately explained what you wanted to do for real.
If you want to display the time then yeah, don’t use a coroutine wait at all. Just subtract Time.deltaTime from the remaining duration and display that as a formatted value in your UI. If that’s what you were trying to do with the looped wait for seconds then…yeah don’t do that ![]()
What I’ve done previously, which is overkill, is have one coroutine do the countdown AND the entire delay. To avoid cumulative error, it saves the start time, finish time and the integer seconds counted off. Each yield, for the countdown, it recomputes the correct waiting time until the next second: (savedStartTime+nextIntSecond) - Time.time.
But I think the OP’s issue is elsewhere.
I said dude
plz see the first post!
“Suppose I want to count down a timer and when it is zero,” I thought it is obvious that a timer counts down per sec
“Counting down” and “displaying the current timer value” are potentially two separate things.
The critical information is this:
WaitForSeconds will be accurate to within:
- your system clock’s error margin*,
- plus up to the duration of about^ one frame,
- but possibly with consideration for floating point accuracy*^ if your timer is really long.
In your example of waiting for one second two hundred times (presumably so you can update your UI), the total error is large because it’s the accumulated error from two hundred waits for short durations. Assuming your game is running at 60hz the accumulated error there could be up to ~3.3 seconds, which is a really long time for your UI to be displaying an incorrect state!
As the others have said, I personally wouldn’t think of a coroutine as the best solution here. Short ones make things inaccurate, and (as far as I’m aware) you can’t query the remaining time on a long one. You could separately track it yourself, but then you’re setting up your own timer anyway and should just use that directly - a “Single Source of Truth”.
On the note of a “Single Source of Truth”, if the architecture of your game allows it I’d use something rough (like a progress bar) for user feedback on remaining time, and rely on server messages to tell you when the function is and isn’t available. I’ve little experience on networked projects, though, so others may have better advice there.
- Negligibly small.
^ The “about” is to cover odd cases, such as order of execution changing.
*^ Also negligibly small for any sane use of a coroutine, but for the sake of completeness read this.
It really feels like everyone is trying to over-complicate this. The inaccuracy we’re talking about is, at most, the entire length of a single frame. You can still do it in a coroutine but if you want to display the value then you can’t use WaitForSeconds. That’s all.
var duration = 200f;
while (duration > 0)
{
duration -= Time.deltaTime;
timer.text = duration.ToString(); // but probably want to format more nicely
yield return null;
}
That’ll never finish before 200 seconds (as stated already) and, given that you’d send an ack from the server, the network latency plus the fact that it’ll be a shade over 200 seconds means that the client will never be able to request the upgrade before the timer runs out (without cheating of course).
yes we discussed before. Thanks
easily use yield return null and time+=time.deltaTime and round it.