I eventually got round to recreating the old roblox legacy animator inside modern roblox huzzah!
One of the many smaller issues I’m facing is the fact that if you are not 60fps then the fadetime will look as if it goes ‘fast’
just wondering if theres any smart people out there that can help; ive printed out my trackweight value 0-1 and it seems to be the same each fps;
visually the fadetime happens so fast!
60fps;
more than 60fps (240+);
I’ve provided the relevant code you should need.
It’s literally the exact same as the c++ variant so I’m not quite sure why it appears to ‘fade’ faster on higher fps
call;
if kfTime >= newAnimation.Length then
if newAnimation.Looped then
newAnimation.animStart = tick() --// restart
elseif not newAnimation.Looped and not newAnimation.ended then
newAnimation:Stop(autoFadeTime)
end
end
anim step
local now = tick()
local kfTime = newAnimation:getKeyframeAtTime(now)
local trackWeight = newAnimation:getWeightAtTime(now)
if newAnimation.ended or not newAnimation.isPlaying then
kfTime = newAnimation.Length
end
if newAnimation.ended and newAnimation.name == "GetUp_PanicStart" then -- will pass btw!!
local fadeOutAlpha = ((now - newAnimation.fadeStartTime) / (newAnimation.fadeEndTime - newAnimation.fadeStartTime))
--warn(trackWeight )
trackWeight = math.lerp(newAnimation.fadeStartWeight, newAnimation.fadeEndWeight, fadeOutAlpha)
--warn("2; " .. trackWeight)
end
local newPoses = newAnimation:apply(jointPoses, newAnimation.lastKeyframeTime, kfTime, trackWeight)
newAnimation.trackweight = trackWeight
--// reweight based on trackweight
ipose.weight = helper.lerpF(0.0, ipose.weight, trackweight)
ipose.maskWeight = helper.lerpF(1.0, ipose.maskWeight, trackweight)
fadestarweight and fadeendweight are 0 or 1
fadestarttime and fadeendtime are tick() and tick() + fadeTime respectively;
Doesn’t exactly make sense 2 me but also makes sense?
My friend gave me a 60fps limiter and it worked wonders; just wondering if i can fix this visual problem in anyway?
I don’t understand what you mean. I don’t see an issue. When you are running at higher frame rates, the fade time seems to move too quickly. This happens because the time between frames is smaller at higher frame rates, making the fade complete faster than expected. I think that’s what you’re talking about, no?
noo ive printed trackweight on both fps and they both reach 1 at the same time but for some reason higher fps makes the fade complete faster yet the trackweight is still just 0.8 and it can be finished visually?!!
Higher FPS just means more updates per second. So even if your trackWeight is the same, the fade looks faster because it’s updating more often. It’s just how FPS works. Fix your timing to sync with the actual fade, not the FPS. I don’t think you’re understanding something.
in my head; it should still be the same length as 60fps visually; just smoother!
but when i look at it it appears to complete the fade quicker then it is supposed to it literally is speeding up time which is impossible
The fade should look smoother at higher FPS, but the actual time for the fade is still the same. If it’s completing quicker, you’ve messed up your timing somewhere. FPS just updates it more frequently, but the total duration of the fade shouldn’t change. You’re probably syncing it wrong.
Well, if the trackweight is still going from 0 to 1 correctly, then it’s not the issue with the fade duration. It sounds like you’re not syncing the fade right with the time. FPS is just updating more often, but it shouldn’t be affecting the fade. Maybe try checking your timing logic again.
You did not provide enough code, and I do not understand what is going on in the code that you provided. But what is likely happening is that this code is running sixty times per second when the framerate is sixty frames per second. When the framerate increases to 120 frames per second (twice as many frames as 60), the code runs twice as many times per second, which makes it fade two times faster. What you should do is multiply the linear interpolation alpha (some people call it the interpolation theta) by the amount of time that has passed since the last frame. What I mean is, the number that is between 0, and 1 in the linear interpolation.
local fadeTime = 2
local now = tick()
local startWeight = 0
local endWeight = 0
local startTime = now
local endTime = now + fadeTime
while task.wait() do
local alpha = math.clamp((tick() - startTime) / (endTime - startTime), 0, 1)
local weight = (startWeight + (endWeight - startWeight)) * alpha -- lerp
print(weight)
if alpha >= 1 then
break
end
end
essentially what my code is doing is this; i dont know why it is finishing faster visually on higher fps yet the value remains properly set as the alpha increases
and i’ve tried multiplying the thingy but it made it way longer, my autofadetime is 0.6
function newAnimation:getWeightAtTime(t, dt)
if t >= newAnimation.fadeEndTime then
return newAnimation.fadeEndWeight
elseif t <= newAnimation.fadeStartTime then
return newAnimation.fadeStartWeight
else
--local interval = (newAnimation.fadeEndTime - newAnimation.fadeStartTime)
--return ((time - newAnimation.fadeStartTime) / interval) * newAnimation.fadeEndWeight + ((newAnimation.fadeEndTime - time) / interval) * newAnimation.fadeStartWeight
local alpha = math.clamp((t - newAnimation.fadeStartTime) / (newAnimation.fadeEndTime - newAnimation.fadeStartTime), 0, 1)
return math.lerp(newAnimation.fadeStartWeight, newAnimation.fadeEndWeight, alpha * dt)
end
end
By multiplying the alpha with dt, you’re making the fade time dependent on the FPS, which makes it look faster at higher FPS. You should use the alpha value on its own, without multiplying it by dt, so the fade time stays the same across different FPS and appears consistent.
it shouldn’t be fading two times as fast because I’m using tick() and tick() + fadetime
see stop;
function newAnimation:Stop(fadeTime)
fadeTime = fadeTime and math.max(fadeTime, 0) or 0.100000001
if fadeTime < 0 then
--for i, anim in pairs(animator.activeAnimations) do
-- if anim == newAnimation then
-- table.remove(animator.activeAnimations, i)
-- end
--end
fadeTime = 1/100000000000 --// ensure that motorposes are reset
end
local currentTime = tick()
newAnimation.fadeStartWeight = newAnimation:getWeightAtTime(currentTime)
warn(newAnimation.fadeStartWeight)
newAnimation.fadeStartTime = currentTime
newAnimation.fadeEndTime = currentTime + fadeTime
newAnimation.fadeEndWeight = 0
newAnimation.fadeLastT = currentTime
--print(newAnimation.fadeStartWeight)
--warn("fade start weight above!")
newAnimation.ended = true
newAnimation.isPlaying = false
end
local runService = game:GetService("RunService")
local fadeTime = 1
local now = os.clock()
local startWeight = 0
local endWeight = 1
local startTime = now
local endTime = now + fadeTime
local totalTime = endTime - startTime
local startTime = os.clock()
local alpha = 0
while true do
local deltaTime = task.wait() -- try doing task.wait(1/10) to simulate a framerate of 10 frames per second. -- runService.Heartbeat:Wait()
alpha = math.clamp(alpha + deltaTime/totalTime, 0, 1)
local weight = startWeight*(1-alpha) + alpha*endWeight -- lerp
print(weight)
if alpha >= 1 then
break
end
end
print(os.clock() - startTime) -- This should be roughly equal to the fadeTime variable even when the framerate is not 60fps give or take a tiny fraction because it can't be 100% perfect.
No. If the interpolation is not dependent on the framerate, it’s speed will change depending on the framerate. If you multiply the alpha by the deltatime, then it will slow down the linear interpolation to account for this higher framerate or it will speed it up if the framerate is too low, so in theory (and in practice) it should finish at roughly the same speed.