How to implement "wait at least this long" in Unity/C#


Sometimes you want a thing to last a certain amount of time. When the user clicks a button, the popup afterwards sometimes shouldn't immediately appear. You want to convey the feeling the game or server is doing something important, even when it isn't. Failing fast is good in the ideas world. But in the UI/X world, sometimes your error messages need that meaty feel. And nothing says work got done like a subtle delay. Use sparingly. Delays may be inevitable, but they are annoying.

// Somewhere in your code
void DoAThingButNotTooFast() {
    StartCoroutine(DoingAThing(2.5f));
}
IEnumerator DoingAThing(float duration) {
    Func<IEnumerator> waitABitLonger = Game.WaitFor.Minumum.Real(duration);
    yield return somethingThatMayTakeLessThanDuration();
    yield return waitABitLonger();
    // at least 2.5 seconds will have transpired
}
// WaitFor.cs
using System;
using System.Collections;
using UnityEngine;
namespace Game.WaitFor {
    public static class Minimum {
        // Use actual time
        public static Func<IEnumerator> Real(float duration) {
            float start = Time.unscaledTime;
            return () => {
                float now = Time.unscaledTime;
                float elapsed = now - start;
                float timeLeft = duration - elapsed;
                return WaitReal(timeLeft);
            };
        }
        // Use scaled time
        public static Func<IEnumerator> Scale(float duration) {
            float start = Time.time;
            return () => {
                float now = Time.time;
                float elapsed = now - start;
                float timeLeft = duration - elapsed;
                return WaitScale(timeLeft);
            };
        }
        static IEnumerator WaitReal(float duration) {
            yield return new WaitForSecondsRealtime(duration);
        }
        static IEnumerator WaitScale(float duration) {
            yield return new WaitForSeconds(duration);
        }
    }
}

Now you might ask why I duplicate the Real and Scale code except for a few lines of code in each. Well, that's a much longer discussion about code design and machine optimization. But the bottom line is that these functions do less individually than a single function with three if/else statements. It's easier to read, understand, and the compiler can do a lot more work on them independently. Most of the time, though, you should try to pull out common bits of code. But this is one of the examples when you probably shouldn't. Though it wouldn't really hurt anything if you did. I tend to get specific like this in my "library" code.

Get Against the Tide

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.