- Home /
Run coroutine X amount of times in Y seconds?
I am trying to keep track of military time in my game by using a coroutine that would supposedly loop through 2400 times in the number of seconds it takes for a complete day cycle in my game. I'm using 30 seconds for testing purposes.
Here's my code.
public float milTime;
public int dayLength = 30;
void Start () {
StartCoroutine("ChangeTime");
}
public IEnumerator ChangeTime() {
for (int t = 1; t < 2400; t += 1)
{
milTime = t;
yield return new WaitForSeconds(dayLength/2400f);
}
}
In theory, this could should work, right? I increment military time by 1, starting at 1, waiting 30/2400 seconds between each increment. The problem is, it doesn't. The military time counter is considerably far behind by the time 30 seconds go by. By a couple hundred. I would guess that this would work if one day was 2400 seconds (2400/2400 = 1, increment by 1 every 1 second), but I'm not about to wait 2400 seconds to find out. Is this a problem with the way Unity handles such small numbers as 30/2400 as a wait time, or do I have a logic error somewhere? Thank you!
Answer by nintorii · Aug 16, 2014 at 06:06 AM
Sorry if the question was hard to understand or I didn't fully comprehend some of the suggestions I got, but here's the solution I found to my problem. This will get my value from 0 to 2400 in the time specified without much margin of error.
public float milTime;
public int dayLength = 30;
void Start ()
{
StartCoroutine(SetTime (0, 2400, dayLength));
}
private IEnumerator SetTime(float startValue, float endValue, float moveTime)
{
float curTime = 0f;
while (curTime < moveTime)
{
milTime = Mathf.Lerp(startValue, endValue, curTime / moveTime);
curTime += Time.smoothDeltaTime;
yield return null;
}
}
Answer by Eric5h5 · Aug 15, 2014 at 11:01 PM
Waiting for .0125 seconds won't really work, since the Unity update rate is tied to the framerate. It will wait for the nearest amount to .0125 that's possible, but it will almost always be off by a relatively significant amount each yield, and that will become cumulatively worse over time. (Unless the framerate is insanely high.)
It would be better to have a timer that you set to 0 in Start, then add Time.deltaTime * someFactor every frame.
That answers my question, thank you! Your suggestion works, but only if I find a constant by hand each time I want to change the time of a day cycle, and even then, it's slightly off. Is there any way to use the timer method using the length of the day as a variable?
@Yoman It answered my question about whether or not my solution was correct and it was just a Unity/frame-rate issue or my code's logic, but it doesn't really solve the problem at hand. Still useful though. edit: still unable to find a solution :/
I'm not really sure I understand the issue...you're just counting from 1 to 2400 at an arbitrary rate, yes? So you'd multiply Time.deltaTime by that rate, no need to find anything by hand. Although I should mention that this isn't technically military time since hours have 60 $$anonymous$$utes in them, not 100; not sure if that matters for what you're doing.
Answer by Kiwasi · Aug 16, 2014 at 04:12 AM
Use a custom property to convert the game time into your time.
public float milTime {
get {
return (Time.time/30);
}
}
Its also possible to correct for offset errors in your coroutine by comparing the cycle number to Time.time
Your answer
Follow this Question
Related Questions
Lerp to position, after a while come back, problem occured using Coroutines 1 Answer
How to wait for Start() to run when calling InstantiateObject() 1 Answer
RPG Action Progress Bar always same speed 1 Answer
A loop FOR waits for a coroutine to end 1 Answer
Time Manager Class Implementation Like Coroutine in Unity 1 Answer