Not sure what is happening, but my while loop isn't ending

Before anybody points it out, I know that my code is highly inefficient, but I am doing this for testing purposes as I am a beginner at scripting.

Essentially, I am trying to make a loading bar that moves using the Scale of the frame. Once again, I know that this is inefficient!

I haven’t been able to find a solution to this anywhere else, so if anybody knows how to fix this I would greatly appreciate the help! :grin:

The script does scale the frame but it does not stop at the desired scale.
Here is my code:

local loading = script.Parent.loading
local bar = loading.bar
local loadtext = loading.TextLabel

local function loadSequence()
	while bar.Size ~= UDim2.new(0.987, 0, 0.629, 0) do
		wait(0.01)
		bar.Size = bar.Size + UDim2.new(0.001, 0, 0, 0)
	end	
end 

loadSequence()

I feel your issue is because of floating point errors, the size you want might not necessarily be 0.987 on the x scale, it could be 0.9866666666666666, or 0.62888888888888 on the y scale or something. Also I wouldn’t recommend hardcoding the desired position.

This is because the addition happening in the loop will simply never equal the required condition to break.

I wouldn’t use this method for creating a loading effect. Use tweens instead.

1 Like

Ok I know you probably won’t know how to tween, but it’s simple.

I suggest using tweening instead.

Hi there, thanks for your reply!

I just noticed that, and have changed the addition from 0.01 to 0.001 but it is still not stopping. Any other ideas?

Also, I know that I can use tweens (although have no idea how to use them) but for the time being I just want to test things out and try with scale.

How about you just check for the x scale instead of the whole thing since that’s the only thing you’re changing, then you can do (so even floating points happen when the Scale is higher or equal to 0.987 it’ll stop)

while bar.Size.X.Scale < 0.987 do
   wait(0.01)
   bar.Size = bar.Size + UDim2.new(0.001, 0, 0, 0)
end
1 Like

This is not true in the slightest, you certainly can use “==” or “~=” on two different objects, nothing mandates that to use “==” or “~=” you have to be referencing the same object.

Regardless, his method would work, it is his method of detecting the end call that is the issue.

However, to hold true to your point, the more beneficial method of detecting this would be something along the lines of:

bar.Size.X.Scale < 0.987

As an alternative I would just use lerp in a for loop.

for i = 0,1,0.001 do
    wait(0.01)
    bar.Size = bar.Size:Lerp(UDim2.new(0.987, 0, 0.629, 0), i)
end

But, as others have suggested Tweening would probably be the most appropriate choice for this problem.

I believe this should do the trick.

local Bar = loading.bar

function TweenBar()
    local Time = .3				
			
    local SizeGoal = UDim2.new(0.987, 0, 0.629, 0)
	
	local TweenInformation = TweenInfo.new(
	
		Time,
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.Out,
		0,
		false,
		0
	
		)
	
	local NewTween = TweenService:Create(Bar, TweenInformation, {Size = SizeGoal})
	
	NewTween:Play()

end

Definitely look into tweening, it’s very useful.

You will not achieve the desired result using a loop without overcomplicating it by checking specific properties and doing more/less than comparisons. It’s best to just use a tween. Alternatively, you can manually interpolate it yourself if you know how many steps or how long you want it to take.

@Shinjaa’s lerp solution would work, although I suggest having the loop run from 0 to 1000 instead, and having the alpha value just be i / 1000 to avoid further accuracy issues.

You can also use the tweening functions that are inherited by the GUI Object itself, being TweenPosition

1 Like

That’s true, there is a TweenSize function for UI objects that doesn’t require your own function.

1 Like

I’m sorry for my mistake :sweat_smile: But I would prefer use the TweenService.

you could use

repeat
bar.Size = bar.Size + UDim2.new(0.001, 0, 0, 0)
until bar.Size == UDim2.new(0.987, 0, 0.629, 0)

or

while bar.Size ~= UDim2.new(0.987, 0, 0.629, 0) do
		wait(0.01)
		bar.Size = bar.Size + UDim2.new(0.001, 0, 0, 0)
                if bar.Size == UDim2.new(0.987, 0, 0.629, 0) then
                break
	        end	
         end

which should do the same thing: Breaking out of the loop.

Thanks for your response!
TweenSize worked, I can’t believe how much quicker that was to do than working with size normally. It was also less complicated than I thought it would be.
I’ll look further into tweening for sure!