For loop inaccurate for timer

Context:
I’m currently making a XP system and I’m animating an XP label to increase in XP. The XP is display in the label as such:
image


Issue
When animating the xp, I use a for loop which increases the text label every 0.01 seconds. I add the for loop to itself based on a calculated addBy. I want the loop to last exactly 1 second so I use this equation:

local addBy = goal * (0.01 * TWEEN_DURATION)

Potential Reasons
However, I’m facing issues with the accuracy of the loop. I think that some potential reasons is that:

  1. The for loop is inaccurate at matching 1 seconds worth of animation because the 0.01 wait faces small inaccuracies which build up over time

  2. The equation may be incorrect.


Code
Here is the code:

local TWEEN_DURATION = 1

function animateXp(start, goal, max, label)
	local addBy = goal * (0.01 * TWEEN_DURATION)
	for i=start, goal, addBy do
		task.wait(0.01)
		label.Text = i .. "/" .. max
	 end
end

Call For Action
I would really appreciate if anyone could find a solution to my issue. Consider the potential reasons and tell me what you think.

task.wait() returns the exact number of time that has passed so you should probably use that instead of 0.1

local timePassed = task.wait(0.1) — timePassed stores the exact time that the thread has yielded for

0.1 is too choppy though for the addBy. I probably need to switch timer mechanism but I do not know much about them. For example maybe like render stepped but as mentioned I don’t really know much about these other systems.

Oh that was just an example. Works the same for any number including 0.01

Thank you for helping but the script still doesn’t work and I do not see how storing the information about how much time has passed will help make the loop anymore accurate.

The current loop is

local TWEEN_DURATION = 1

function animateXp(start, goal, max, label)
	local addBy = goal * (0.01 * TWEEN_DURATION)
	for i=start, goal, addBy do
		task.wait(0.01)
		label.Text = i .. "/" .. max
	 end
end

but the loop is longer than my tween duration. Heres a video showing this:

If you could clarify how this can help me such as showing the correct function code It would clear up any confusion on my part.

I realized the video was screwed up so I fixed it

see how the loop overshoots the target by almost twice the tween duration on the things like the frame. Also the reason I am calculating the addBy and not the wait in between each iteration is cause task.wait() can only go so low and can be inaccurate for larger numbers.

1 Like

Try this out

local TWEEN_DURATION = 1

function animateXp(start, goal, max, label)
	local amountToAdd = goal - start
	local timePassed = 0
	while true do
		timePassed += task.wait()
		if timePassed > TWEEN_DURATION then
			label.Text = goal .. "/" .. max
			break
		else
			label.Text = start + amountToAdd * timePassed / TWEEN_DURATION .. "/" .. max
		end
	end
end

You could try doing this instead of a for loop:

local TWEEN_DURATION = 1

function animateXp(start, goal, max, label)
	local start = tick()
        while wait() do
            local now = tick()
            local elapsed = now - start
            if elapsed > TWEEN_DURATION then break end
            label.Text = math.floor(elapsed / TWEEN_DURATION) * goal .. "/" .. max
        end
end

Thanks! This worked!

I tried this however it didn’t work

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.