简体   繁体   中英

How to subtract hundreds/thousands of times a second in unity?

I am currently working on an idle game but am having trouble with time. The code below runs when a business is activated in order to prevent the player activating the business again before it finishes. The variable "subtractTime" is the time it takes for the business to finish multiplied by 100.

There are different kinds and levels of businesses that require a different amount of time each. When you upgrade the business to certain levels, the time it takes to make money cuts in half.

When the time is lower than a second, the code below works as it is fast enough to not be able to tell it can't keep up. However, when dealing with larger amounts of time, such as 6 seconds, it does not subtract fast enough.

while (subtractTime > 0)
        {
            completed = false;
            yield return new WaitForSeconds(.01f);
            subtractTime = subtractTime - 1;
        }

There are multiple ways to achieve that.

One simple way is to just wait until the timer has finished:

IEnumerator StartCooldown(float subtractTime) {
    subtractTime *= 0.1f;
    completed = false;
    yield return new WaitForSeconds(subtractTime);
    completed = true;
}

The only problem with this is that you don't have the remaining time updated as time passes, which may be useful for other things such as a cooldown bar.

A workaround to that would be something like this:

IEnumerator StartCooldown(float subtractTime) {
    subtractTime *= 0.1f;
    completed = false;
    while (subtractTime > 0) {
        subtractTime -= Time.deltaTime;
        yield return null;
    }
    completed = true;
}

Time.deltaTime is just the time elapsed between the last frame and the current one, and yield return null just stops the execution of the Coroutine and resumes it on the next frame.

Note: you can remove the subtractTime *= 0.1f; line in both examples if the value you pass to the function is in seconds, since both examples work with time measured in seconds:)

The problem is the fixed time WaitForSeconds(.01f) because you don't know if the players' CPU can keep to that schedule, it may be too slow or be busy on other tasks. Instead we use the time it took to complete the game loop each frame, which is called Time.deltaTime :

IEnumerator ITimeSomething(float timeLimit) 
{
    float t = 0;
    while (t < timeLimit) 
    {
        t+= Time.deltaTime;
        yield return null;
    }
    
    // do something when the time runs out
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM