Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

My repeat won't stop even after it reaches the until value?

game.ServerStorage.Megafans.Fan1.State.Changed:Connect(function(state)
    if state == "Starting" then
        local speed = 0.05
        repeat
            speed = speed + 0.0005
            print(speed)          script.Parent.Parent:SetPrimaryPartCFrame(script.Parent.Parent:GetPrimaryPartCFrame()*CFrame.fromEulerAnglesXYZ(0,speed,0))
            wait()
        until speed == 0.3
    elseif state == "Running" then
        repeat
            script.Parent.Parent:SetPrimaryPartCFrame(script.Parent.Parent:GetPrimaryPartCFrame()*CFrame.fromEulerAnglesXYZ(0,0.4255,0))
            wait()
        until state ~= "Running"
    end
end)

So the first repeat isn't stopping, even after it prints 0.3, I can't figure out why. (the one below)

repeat
            speed = speed + 0.0005
            print(speed)          script.Parent.Parent:SetPrimaryPartCFrame(script.Parent.Parent:GetPrimaryPartCFrame()*CFrame.fromEulerAnglesXYZ(0,speed,0))
            wait()
        until speed == 0.3

2 answers

✓ Accepted answer

##Reason:

This is because of the way that computers store decimal numbers.

In short, since computers can only use a few bits to describe decimal numbers, they have to make some approximations, and that results in values like 0.3 turning into something more like 0.299999999999999981.

Lua tries to round values when displaying them to make this less of a problem for the end user, but internally, they still act like this.

If you want to learn more, you can search up "floating point error" or "floating point imprecision", but the simple fix is to just check if speed is greater than 0.3 rather than exactly equal to it

repeat
	speed += 0.0005 -- Compound operators winning
	-- When I have super  long CFrame operations like this I like to split them into several lines
	script.Parent.Parent:SetPrimaryPartCFrame(
		script.Parent.Parent:GetPrimaryPartCFrame()
		* CFrame.fromEulerAnglesXYZ(0, speed, 0)
	)
	wait()
until speed >= 0.3

Also, you probably didn't notice this, but there's another error with the second repeat loop.

Because state is defined within the scope of the function, that means that the code inside that function will only ever know what the value was when the event fired.

You can fix that by simply making an upvalue (i.e. a variable that's "up" above the function) for the state and then setting that to state.

local state = "Starting"

game.ServerStorage.Megafans.Fan1.State.Changed:Connect(function(value)
	state = value
    if state == "Starting" then
        local speed = 0.05
repeat
			speed += 0.0005 -- compound operators winning
			-- When I have super long CFrame operations like this I like to split them into several lines
			script.Parent.Parent:SetPrimaryPartCFrame(
				script.Parent.Parent:GetPrimaryPartCFrame()
				* CFrame.fromEulerAnglesXYZ(0, speed, 0)
			)
			wait()
		until speed >= 0.3
    elseif state == "Running" then
        repeat
			script.Parent.Parent:SetPrimaryPartCFrame(
				script.Parent.Parent:GetPrimaryPartCFrame()
				* CFrame.fromEulerAnglesXYZ(0, 0.4255, 0)
			)
            wait()
        until state ~= "Running"
    end
end)

####Re-edited by JesseSong!

1 comment

0

Fixed grammatical issues in your answer

I can't really explain why is it not working as i am confused by that too but in your case if you ever tried doing print(n == 0.3) it always prints out false, i don't know why, but you can fix the problem using >= for some reason. If you don't know these symbols, here are their meanings: >= higher or equal to, <= lower or equal to. So you can try this:

repeat
	speed = speed + 0.0005

	-- your code n stuff	

until speed >= 0.3 -- >=

If it does not help, don't accept the answer.

This discussion is preserved as it was. New answers, comments, and votes are closed.