Sorry for the title, I wasn't sure how to describe the problem in a short way. Basically, I have a slider connected to a float which is the stamina you see on the slider(called tempStamina) and I have another float, which is the actual stamina(called currentStamina). I have another script basically saying, that if you press space the real stamina gets subtracted by 2 and I the stamina script says:
if(tempStamina < currentStamina){
tempStamina -= 0.1f;
}
My problem is that when I press space in game the tempStamina doesn't go down until it's 8 but it goes down until it's 7.999993 (it's the same every time). I wanted to ask if anyone knew why this is happening and could help me fix it? I've tried rounding the number with Mathf.Round(tempStamina); in Update() but it didn't work for some reason. Btw the if() is also in Update
#Float behaving weirdly
1 messages · Page 1 of 1 (latest)
What you are experiencing is called "floating point imprecision".
The System.Single data type (aliased as float for convenience) sacrifices accuracy for a larger value range. That is also why you should never directly check equality between float values - even if they appear to be the same, they may just be off a bit - literally - and not return the expected result.
In this case, you likely don't need complete precision. But when you do, consider using a double or decimal instead (for reference, see the MSDN article on floating point numeric value types).
That being said, doing fixed-value additions or subtractions inside Update to create change over time is not a good idea, because you will end up with inconsistent results:
Assume you have a variable with a value of 60, and you decrease it by 1 inside Update.
For a player running the program at 60 fps, it will take 1 second until the variable reaches 0.
For a player running the program at merely 30 fps, it will take twice as long, because the Update method only runs once per frame.
To make changes over time consistent, you should factor in Time.deltaTime. This [FAQ entry](#faq_unity message) describes it a little more in depth.
Are you aware of floating point errors
Wait zenvin beat me lol
also does it really need to be exactly 8
yeah, because stamina is something the player is supposed to have and if it always decreases by more than 2 then you can dash less times than I want the player to be able to dash
cause I‘m using stamina to dash
So I tried using ints now and it works (it now doesn't go down by 0.1 but by 1 and the max isn't 10 anymore but 100) but the slider doesn't go down. In update I have staminaSlider.value = tempStamina; but the slider doesn't change when temp slider goes down.
nvm it worked
It doesn't sound like it needs to be exactly 8
It doesn't matter anymore I was able to fix it by using ints instead of bools
I mean floats
not bools
sorry
I think so
let me check rq
it seems like I didn't
but I'm also unsure on how since I can't really multiply it by Time.deltaTime since they're ints
one solution is not to use ints
but if I don't use ints I won't be able to recognise when tempStamina and currentStamina are the same so I know when I'm able to refill stamina
i think you are limiting yourself because of an unoptimal way of doing something
as I mentioned before, do you need it to be exactly 8
I think so
When I get back I can try to do it without it being exactly 8
even though idk if it's going to be easy
because I'm still a beginner and don't know a lot
if(!staminaIsBeingUsed && currentStamina < maxStamina && tempStamina < maxStamina && currentStamina == tempStamina)
{
startRefillTimer += Time.deltaTime;
if(startRefillTimer >= endRefillTimer)
{
staminaIsRefilling = true;
startRefillTimer = 0f;
}
}
I think I need it to be 8 to be able to do this
How you've coded it yes, it requires that it is exactly 8
But are there other ways to achieve the behavior you want?
Could you tell me another way? I‘m unsure on how to do it differently
for sure!
so instead of using ==, you could use >=. do you understand what how this would work?
in general, due to floating point imprecision its a bad idea to use == to compare floats
oh, yeah, I think I understand
ok, tyvm
so in the other code I‘d have if(currentStamina < tempStamina){
tempStamina -= 0.1f * Time.deltaTime;
}
?
or how would I implement Time.deltaTime
assuming I changed both back to floats
yes, you would need to change things back to floats in order to use time.deltatime (technically there are cursed ways around this but that's another story)
and 0.1f * Time.deltaTime is correct?
what is tempStamina
i'm not sure exactly what you're doing but it looks okayy ?
it‘s the variable that is shown in the slider
so when currentStamina get‘s reduced you don‘t see it but that way tempStamina knows how much to go down
ok, ty
I‘ll try it out once I get home
im confused
I could try sending the whole script if that helps but idk
https://pastebin.com/2arNKBm5
this is still before adding the Time.deltaTime
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
why don't you want the stamina bar to visually go down when its being used?
because if it goes down by 2 it doesn‘t go down smoothly but it jumps down from 10 to 8
but I want it to look smooth
so I have a variable that jumps to 8 and another one that follows by becoming smaller by .1 very often
so you want the stamina bar to go down smoothly?
by using time.deltatime, your variable already goes down smoothly
so if I just multiply by Time.deltaTime everytime I subtract from currentStamina it goes down smoothly?
like if I say currentStamina -= 2 * Time.deltaTime; it would go down smoothly?
do you understand the origin of time.deltatime and why it is useful?
I don‘t really
I only know it‘s to make everything the same with different fps and that it marks the time basically
[]deltatime you can read this
Time.deltaTime is the amount of seconds it took for unity to calculate and render last frame. Let's say your game runs at a constant 100 frames per second, then Time.deltaTime will be 0.01f every frame. But games usually don't run at a constant frame rate so Time.deltaTime compensates for that.
For example:
private void Update()
{
transform.position += new Vector3(0f, 0f, 10f);
}
private void Update()
{
transform.position += new Vector3(0f, 0f, 10f) * Time.deltaTime;
}
In the first example; if the game runs at 100 fps, the object will move twice as fast compared to if the game ran at 50 fps.
But let's look at the second example:
If the game is running at 100 fps: the object will move by (10 * 0.01) 0.1 units every frame, therefore moving (0.1 * 100) 10 units every second.
If the game is running at 50 fps: the object will move by (10 * 0.02) 0.2 units every frame, therefore moving (0.2 * 50) 10 units every second.
If the game is running at 20 fps: the object will move by (10 * 0.05) 0.5 units every frame, therefore moving (0.5 * 20) yet again 10 units every second.
idk how to explain the 2nd one
ty
This I knew, but how would I tell the slider to go down smoothly? I‘m still very unsure, sorry
games are kind of a trick right
objects never move smoothly, we always increment their position or value or whatever by some value. but if we do it by a small enough value, and do it often enough, we can trick our brains into thinking of smooth behavior
yeah I know
that‘s what I meant
sorry, I meant to say that
that‘s why I decrease tempStamina by 0.1
to clarify, you're already decreasing the stamina by a small value every frame/every time update calls, that makes it seem smooth
but by multiplying by time.deltatime, you're making sure that the decrease is framerate independent (the stamina does not decrease faster or slower depending on your fps)
yes, I understand that
could you clarify what you're asking here then?
but, like, how do I add Time.deltaTime so it is frame independant
like, where do I multiply by Time.deltaTime
you multiply wherever there is a framerate dependent operation going on
just think to yourself, "if the user has a really high fps, is that going to affect this calculation?"
if so, you should multiply by time.deltatime
for example, before you had (in update) tempStamina -= 0.1; if the user has a high fps... what happens?
yeah, and I know I have to do this with my stamina going down/back up
he would lose stamina quicker
okay so it looks like you know?
yeah, but I‘m unsure where exactly in the code
would it be behind the .1?
like tempStamina -= 0.1f * Time.deltaTime;
?
that‘s the only one that comes to mind
alright ya that's what i would do
haha its no waste that's what we are here for
you're welcome! you as well