Hello, I’m using a gun engine to make guns, but a big downside of it is that its RenderStepped/Animation functions aren’t independent of framerate. The script is meant to run at 60 FPS, and I found this out because that was the only framerate range where the animations were smooth. When I fpsunlocked and was getting 150+, it would be 2 times or more the original speed. Same thing with 30, except that it would be around half-speed. I’ve already identified the part of the code which controls the speed, and therefore is the problem (it’s the while loop). Here’s the code (it controls most of the animations)
Utilities.TweenJoint = function(Joint, newC0, newC1, Alpha, Duration)
spawn(function()
local newCode = math.random(-1e9, 1e9) --This creates a random code between -1000000000 and 1000000000
local tweenIndicator = nil
if (not Joint:findFirstChild("tweenCode")) then --If the joint isn't being tweened, then
tweenIndicator = Instance.new("IntValue")
tweenIndicator.Name = "tweenCode"
tweenIndicator.Value = newCode
tweenIndicator.Parent = Joint
else
tweenIndicator = Joint.tweenCode
tweenIndicator.Value = newCode --If the joint is already being tweened, this will change the code, and the tween loop will stop
end
if Duration <= 0 then --If the duration is less than or equal to 0 then there's no need for a tweening loop
if newC0 then Joint.C0 = newC0 end
if newC1 then Joint.C1 = newC1 end
else
local Increment = 1.5 / Duration --Calculate the increment here so it doesn't need to be calculated in the loop
local startC0 = Joint.C0
local startC1 = Joint.C1
local X = 0
while true do -- THIS WHILE LOOP IS THE PROBLEM, BECAUSE IT'S ONLY RUNNING AT 1/60 OF A SECOND.
rs:wait() --This makes the for loop step every 1/60th of a second
local newX = X + Increment
X = (newX > 90 and 90 or newX) --Makes sure the X never goes above 90
if tweenIndicator.Value ~= newCode then break end --This makes sure that another tween wasn't called on the same joint
if newC0 then Joint.C0 = startC0:lerp(newC0, Alpha(X)) end
if newC1 then Joint.C1 = startC1:lerp(newC1, Alpha(X)) end
if X == 90 then break end --If the tweening is done...
end
end
if tweenIndicator.Value == newCode then --If this tween functions was the last one called on a joint then it will remove the code
tweenIndicator:Destroy()
end
end)
end
I tried using ratios and didn’t get good results, as well.
EDIT:
I fixed it, and my ratio idea was 100% accurate, LETS GOOOO!! Turns out I was just doing my debounces and code approach wrong.
It didn’t work, it makes the gun animations all jittery. Unless I used your code wrong.
Here’s what I did:
local Increment = 90 / Duration -- changed the increment from 1.5 to 90 to match the previous ratio after being multiplied by delta (previous ratio was 1.5/ Duration for 60FPS)
local last = tick()
local renderstep = true
if renderstep == true then
rs:Connect(function()
local delta = tick() - last
last = tick()
local newX = (X + Increment) * delta
X = (newX > 90 and 90 or newX) --Makes sure the X never goes above 90
if tweenIndicator.Value ~= newCode then renderstep = false end --This makes sure that another tween wasn't called on the same joint
if newC0 then Joint.C0 = startC0:lerp(newC0, Alpha(X)) end
if newC1 then Joint.C1 = startC1:lerp(newC1, Alpha(X)) end
if X == 90 then renderstep = false end --If the tweening is done...
end)
end
Oh, I didn’t know that. Have you tried using tick()? You can offset the time depending on how much time is lost:
local duration = 5
local t1 = tick()
local stop = start + duration
local t2 = t1
while t2 < stop do
wait()
bullet.Position = disposition:Lerp(t2 - t1)
t2 = tick()
end
Exactly, that’s what I was thinking lol
Used the deltatime argument in renderstepped anyways.
Anyways, since all of the settings were made for 60 FPS, I just used deltatime to get a ratio:
local ratio = 60 / (1/deltaTime)
And then multiplied by ratio where it was needed. It was fixed with 100% accuracy! This was my idea from the very beginning, turns out I just did my debounces and code wrong the first couple of times