Less Error-Prone Way to show Percentages

I think it’s best to use Mathf.Floor instead of Mathf.Round. Reason being that the latter returns 100 when the input is >= 99.5 and <100, meaning that it’s possible for the progress bar to say 100% even when there are tasks still uncompleted. The former, however, avoids this problem; until all the tasks are completed, there’s less potential for showing a misleading percentage.

2 Likes

You can also use integer division as this naturally floors to the lower whole number. See my example below. I have specified that a and b are int, multiplied a by 1000 (also an int) before dividing by b. I then force float division by dividing by 10f (a float) to get one decimal place.

Note that this example should work outside of play mode because I have used OnValidate() instead of Update()

using UnityEngine;

public class Percentage : MonoBehaviour
{
    [SerializeField] TMPro.TMP_Text tmpText;

    [SerializeField] int a;
    [SerializeField] int b;

    void OnValidate() //Update() works but only in play mode
    {
        float percentage = a * 1000 / b / 10f;
        tmpText.text = System.Convert.ToString(percentage) + "%";
    }
}

This method is also possible with floats by using (int) to specify when you want the rounding to occur.

using UnityEngine;

public class Percentage : MonoBehaviour
{
    [SerializeField] TMPro.TMP_Text tmpText;

    [SerializeField] float a;
    [SerializeField] float b;

    void OnValidate() //Update() works but only in play mode
    {
        float percentage = (int)(a * 1000 / b) / 10f;
        tmpText.text = System.Convert.ToString(percentage) + "%";
    }
}

This screenshot uses the latter method

1 Like

Hmmm, I didn’t consider rounding and that it would show up as 100% (“completed”) even if it’s not really completed, nice! :smiley:

Although just to play the devil’s advocate, one could argue if it’s worth worrying about. Even if we don’t show any decimals (so it’s either 99% or 100%), you need a task list of at least 200 elements where 199/200 would in theory round up to 100%. If we show percentages with one decimal, the task list needs to be at least 2000 elements long before there are issues :slight_smile:

Alternatively, you could even go a different route, and pick the number of decimals based on the size of the task list; up to 100 you don’t need decimals, up to 1000 you have one decimal, up to 10’000 you have two decimals, etc. On the up-side, this way every single completed task still shows up in the percentage, even in large lists … On the down-side though, this is just over-engineered for a simple task list (and it’s just about the visual representation)

1 Like

Privacy & Terms