A Good Substitute For yield WaitForSeconds()
Is this function a relatively good substitute for yield return new WaitForSeconds(5)
:
void waitSeconds(float waitTime) {
goTime = false;
float timeWhenWaitCalled = Time.realtimeSinceStartup;
while (goTime != true) {
if (Time.realtimeSinceStartup > (timeWhenWaitCalled + waitTime - 0.25) && Time.realtimeSinceStartup < (timeWhenWaitCalled + waitTime + 0.25)) {
goTime = true;
} else {
goTime = false;
}
}
}
I may be incorrectly assuming that most devices are not so slow that they would miss the 0.5 second window? I am also assuming that this function is a lot slower and inefficient, but given the function's purpose I'm not sure that it matters (as long as it is kept out of the Update loop).
Some of the main advantages of this function is that it doesn't have to run in a Coroutine and that it is independent of Time.TimeScale.
Any comments would be appreciated, thank you.
WaitForSeconds is actually timescale dependant, WaitForSecondsRealtime not. And you can also write your own WaitForSeconds. Here is an example from a project (Note it uses some of my framework stuff so it will not compile)
using System;
using UnityEngine;
public class WaitWhileTime : CustomYieldInstruction
{
readonly Func<bool> _predicate;
readonly Action<float> _action;
readonly bool _scaledTime;
readonly float _time;
/// <inheritdoc />
public override bool keepWaiting
{
get
{
_action.SafeInvoke((_scaledTime ? Time.time : Time.unscaledTime) - _time);
return _predicate.Invoke();
}
}
public WaitWhileTime(Func<bool> predicate, Action<float> action = null, bool scaledTime = true)
{
_predicate = predicate;
_action = action;
_scaledTime = scaledTime;
_time = scaledTime ? Time.time : Time.unscaledTime;
}
}
But back to your question. Yeah it is theoretically possible to miss the 0.5 second frame if maxtimestep is bigger than that. also the while does not look safe... But if it just an example it will probably look something like this
bool _goTime;
void WaitSeconds(float waitTime)
{
_goTime = false;
float timeWhenWaitCalled = Time.realtimeSinceStartup;
while (!_goTime)
{
bool isLess = Time.realtimeSinceStartup < (timeWhenWaitCalled + waitTime + 0.25);
if (Time.realtimeSinceStartup > (timeWhenWaitCalled + waitTime - 0.25) && (!_goTime || isLess))
{
_goTime = true;
if (!isLess) { break; }
}
else
{
_goTime = false;
}
}
}
Yeah the while loop kept giving me grief. The custom WaitForSeconds look interesting, but it seems WaitForSecondsRealtime suits my situation best. Thanks for pointing me in the right direction!
I think it is not a good substitute for it.
Coroutines can give the control back to Unity, even if they are not finished. You can start a coroutine, call 'yield return new WaitForSeconds(5)', and you will be able to do anything, and other scripts can be updated as well.
However, when you use this function, you simply freeze the execution for 5 seconds. You can simply test this by logging the time in the Update() function. While you are using your method, the Update() function can not be called, because your function has to finish first to maintain execution order. With using the coroutine, the Debug.Log() function gets called every time it has to.
I am tending to agree, I didn't really realise how important the coroutine was until now. Thanks for the explination.
I don't suppose y'all know if the Coroutines execute differently for iOS vs Android?
I am using WaitForSecondsRealtime i norder to create a delay between checking the internet connection. It executes perfectly on Android, but half the time it seems to crash my entire iPhone.
Your answer
Follow this Question
Related Questions
What's the best way to create a independent clock (that can be sped up by changing the timescale)? 0 Answers
Animation Won't Play Before My Time Freeze. 0 Answers
Wait time after coroutine's wait seconds is complete 0 Answers
How to Make Timer (Score) Count Up Faster? 1 Answer
How can I have Time.maximumDeltaTime be unaffected by Time.timescale? 0 Answers