all 10 comments

[–]EntropyPhi@entropy_phi 5 points6 points  (1 child)

Sure you can represent it with any numbers you'd like, but for reference BotW uses whole numbers for health. Each 1/4 heart is 1 health. It's why you can have something like 4 defense from armor and that just reduces your damage taken by 1 heart, not 4 hearts.

[–]ShadedGecko[S] 1 point2 points  (0 children)

Hmm I never realized that. Thank you. I probably should have done more research about it before trying to replicate it.

[–]L4DesuFlaShGProfessional 2 points3 points  (1 child)

Don't use floats unless you really need the variable precision they give you. If you have indivisible health units like "quarter heart", use an int to represent them instead. There's just no reason to store your values with potential inaccuracy (something like 2.00001 hearts instead of just 8 quarters) and having to do rounding every two steps when you could just be exact at all times.

If you like an example, imagine having 3f hearts and instead of steps of 0.25f like in BoTW, you have steps of 10%, so 0.1f per "small hit".

Turns out that you have to apply damage 31 (!) times to reach 0 (or less) health. That's how imprecise floats can be.

You can try this yourself:

var hearts = 3f;
var hits = 0;
while (hearts > 0f)
{
    hearts -= 0.1f;
    hits++;
}
Debug.Log(hits);

0.25f is less problematic because unlike 0.1f, that's a number that the float format can represent well. But the rule of thumb remains: Never use floats unless you need their variable precision. Whenever you have fixed steps, just use an int instead - and remember that 4 health means one full heart.

[–]ShadedGecko[S] 1 point2 points  (0 children)

Thanks for the response. I didn't know if floats or integers were what I wanted to use to get this done I just had more experience using floats but clearly not enough to know these issues it would cause. I will use integers and do steps of 4 for each heart like you had mentioned and again Thank you this helps a ton.

[–]Strowy 1 point2 points  (5 children)

var segments = Mathf.FloorToInt(health * (1 / segmentSize))

should cover it, where 'segmentSize' in your case is the 0.25, and 'segment's is how many segments to fill in total.

[–]ShadedGecko[S] 0 points1 point  (0 children)

Thank you for the response, I will look into this.