I currently have this script containing a variable called “currentPower” which increases and decreases between 0 and 1 over time to create the effect of the engine slowly warming up.
The problem is the method that im using which just adds the deltaTime divided by the charge time to the variable is very inconsistent and over time speeds up until after a while it almost becomes instant
local currentPower = 0
game:GetService("RunService").Stepped:Connect(function(deltaTime)
if EngineOn then
if currentPower < 1 then
currentPower += deltaTime/2500
else
currentPower = 1
end
else
if currentPower > 0 then
currentPower -= deltaTime/2500
else
currentPower = 0
end
end
end)
is there another way of doing this that is framerate independent and allows me to control the rate of change?
You could use task.wait() and a coroutine to achieve your incrementor. ie:
local currentPower = 0
local powerIncriment = 0.01
function charge(incriment:number)
-- charge up --
while EngineOn do
if currentPower < 1 then
-- wait incriment then add incriment --
task.wait(incriment)
currentPower += incriment
else
currentPower = 1
end
end
-- charge down --
while not EngineOn do
if currentPower > 0 then
-- wait incriment then sub incriment --
task.wait(incriment)
currentPower -= incriment
else
currentPower = 0
end
end
end
-- run the coroutine --
coroutine.wrap(charge)(powerIncriment)
Since we are using a coroutine we can still change the EngineOn value or other logic in the script. I recommend you read up on the coroutine docs to have more control over your script aswell.
You can change the value of incriment in the charge function to decide how fast it will reach 1 or 0. You can also modify the incriment value while the coroutine is running. I recommend you check out task.wait docs I believe its not framerate independent but can be adjusted to last more than a frame, ie: 0.1 seconds / 5 seconds.
Right now, this isn’t doing much in making this fps independent as deltaTime is just being divided, no matter how big or small it may be, you’d want to add an Acceleration value, something like this
local accelerationPerSecond = 2;
local currentSpeed = 0;
RunService.Heartbeat:Connect(function(DeltaTime)
currentSpeed += accelerationPerSecond * DeltaTime
end)
Adding deltaTime to a variable every frame is technically framerate independent, since no matter the FPS the variable should count up by 1 every second, at least that how it worked in Unity, a game engine i used prior to studio. Also, why would multiplying it be different from dividing it?
Right now, your code is just dividing deltaTime (whatever it may be) by 2500. This isn’t consistent because users running at 120FPS will have a delta time that is half of users running at 60fps. How this works is that we have a value that dictates how much X should change in the span of one second, since our code runs every frame, we use deltaTime to multiply the value to add to X, so that X increases by how much it should in the timespan of deltaTime
i.e
local accelerationPerSecond = 2;
local currentSpeed = 0;
RunService.Heartbeat:Connect(function(DeltaTime)) -- for example, say this is running 60 times a second, 60FPS, which translates to a DeltaTime of 0.1667ms.
local speedToAdd = accelerationPerSecond * DeltaTime -- 2 * 0.1667 = 0.3334;
currentSpeed += speedToAdd
-- at this fixed rate of 60FPS, it would take 6 frames for currentSpeed to reach 2.
end
I figured why it was inconsistent in the first place. I was using runService.Stepped’s time parameter instead of its actual deltaTime param. thats why it was speeding up over time.