Quick count up to number function

Does anyone have a quick Coroutine that takes 2 integers and counts up the first integer to the second over 1 or 2 seconds? I just want to animate a deduction of money and would like the price to count down really fast to bring the users attention to it.

Thanks

A more versatile approach would be using a callback in a coroutine like this:

public static IEnumerator LerpOverTime(float aStartNum, float aEndNum, float aDuration, System.Func<float> aCallback)
{
    for (float f = 0f; f < 1f; f += Time.deltaTime / aDuration)
    {
        aCallback(Mathf.Lerp(aStartNum, aEndNum, f));
        yield return null;
    }
    aCallback(aEndNum);
}

This corotuine can be used anywhere like this:

StartCoroutine(LerpOverTime(200,5000,1f, f=>Debug.Log("Current value: " + f)));

This would print “Current value xxx” every frame for a duration of 1 second where xxx is the value that starts at 200 and goes up to 5000. The same coroutine can be used to update a UI Text or do some other fancy things:

StartCoroutine(LerpOverTime(200,5000,1f, f=>uiText.text = f.ToString("0000")));

Here uiText would be a Text component you want to update.

However if you want to be able to dynamically add a value to a variable over time and you want allow to run multiple coroutines at the same time, you could return “delta” values:

public static IEnumerator AddOverTime(float aAmount, float aDuration, System.Func<float> aCallback)
{
    float d = aAmount / aDuration;
    while (aAmount > 0)
    {
        float a = d * Time.deltaTime;
        a = Mathf.Min(aAmount, a);
        aAmount -= a;
        aCallback(a);
        yield return null;
    }
}

The callback of this coroutine will tell you how much amount you should add to your variable each frame. It will run for the given time in seconds and will add in total the given amount.

Example:

public float myVar = 200;
//[...]

StartCoroutine(AddOverTime(250, 2f, d=>myVar+=d));

This will add 250 in total to myVar over the time of 2 seconds. The nice thing is you can run several coroutines in parallel and they all add up to the correct amount.

Note that this method only works properly with float variables. If you want a version for int variables, you have to do it slightly different:

public static IEnumerator AddOverTime(int aAmount, float aDuration, System.Func<int> aCallback)
{
    int d = Mathf.Max(1, aAmount / aDuration);
    while (aAmount > 0)
    {
        int a = Mathf.CeilToInt(d * Time.deltaTime);
        a = Mathf.Min(aAmount, a);
        aAmount -= a;
        aCallback(a);
        yield return null;
    }
}

This should work, I tested it and it seems to work fine. Counts up from startNum to endNum over a fixed period of one second, prints the resulting numbers to console (you could replace the Debug.Log with some other function call, though).

IEnumerator LerpOverTime(float startNum, float endNum) {
	const float WAIT_TIME = 0.01f;
	for (float i = 0f; i < 1f; i += WAIT_TIME) {
		Debug.Log(Mathf.Lerp(startNum, endNum, i));
		yield return new WaitForSeconds(WAIT_TIME);
	}
	yield break;
}

However, it is a quick and dirty solution. The loop variable is floating-point which tends to cause issues due to floating point inaccuracy, in addition, you’ll have to modify it if you want to change the time taken (say two seconds instead of one second).