The Problem with Constant Increments
Animating should always be handled by taking the ratio of elapsed time to set time. There is a very specific reason for doing this besides "just because." To demonstrate why, let's start with an example. Let's say you want to change the transparency of some part instance from 0 to 1, where the transparency increases by 0.1 every 0.1 seconds. Well, one might suggest to use a for loop with a step increment of 0.1 while waiting 0.1 seconds every iteration. Seems obvious, right? Not quite. Let's try it and identify the problem.
for i = 0, 1, 0.1 do
part.Transparency = i
wait(0.1)
end
While this example is reliable in the sense that it will get you from 0 to 1, it is unreliable in how long it will take to do so. The problem here is the for loop, and wait. Waiting a certain amount of time in your script doesn't actually wait that certain amount of time. There is usually some delay, making room for other tasks to take turns running their code. There is also a limit to how little you can wait, which makes sense, since previously mentioned tasks in ROBLOX have higher priorities. Luckily, wait actually returns the real elapsed time, which is how long it actually waited for. This will be useful to us later on.
Solving the Problem with Time
Another issue with the previous example, is that it limits you to how fast, slow, or smooth your animation can be. Nobody wants that. You want to be in control of your animation, and you want it to look smooth. Since we already established that things in your script environment aren't really waiting around for what time you set, then how can we control what the speed or increment of the animation will be? Answer: Use time as the independent variable. You can monitor the progression of your animation by looking at what percent of it has completed using elapsed time divided by set time. Now that we know wait returns elapsed time, we can use this to our benefit by adding together how long our script really waited for, and dividing that by how long we wanted it to wait for.
local duration = 1
local elapsed = 0
while elapsed < duration do
elapsed = elapsed + wait(0.1)
part.Transparency = elapsed/duration
end
This can still be improved, but we're already doing much better by using time. Now, we can use time defined by duration to tell us how fast or slow we want our animation to be, while remaining as smooth as possible.
Improvements?
One improvement to the code above would be removing wait altogether, and replacing it with a RunService step. Why? RunService is responsible for all running activity in your game, so it makes sense that animation would be included in those activities. wait just stops the code running in it's coroutine to go do something somewhere else for an arbitrary amount of time, and who knows how long that time could be. Here's an example of using a RunService step with everything we've gone over:
local RunService = game:GetService("RunService")
local heartbeat = RunService.Heartbeat
local _wait = heartbeat.Wait
local min = math.min
local function animate_transparency(part, value, duration)
local elapsed = 0
while true do
elapsed = elapsed + _wait(heartbeat)
part.Transparency = min(elapsed/duration, 1)
end
end
animate_transparency(part, 1, 1)
This is a much better version of the code we originally started with. Just remember: the thing you want to control is exactly what you should have control over. Don't do something that adds up to 5 seconds with a constant increment, because that doesn't work in the real world. You may even notice in the last example there, I used math.min to make sure the value never exceeded 1. That's because there is still uncertainty, even when using time. It just so happens we can still use time to force the result we want.
Anyway, hope this helped clear things up. I would avoid using for loops for animating. If you have any questions, feel free to let me know in a comment.
1 comment
This is not a request site. Use Roblox Wiki and find things relating to what you're wanting and ask about those things rather than just asking us. Research is important.