In Bloodfest I’m changing the offset of the first person gun model with sin + cos to simulate breathing / movement.
I’m using this code to create an offset value that I can apply to the rig: local posX = math.cos(tick()*movementRate) * xSize local posY = math.sin(tick()*movementRate*2) * ySize
It’s synced with tick() since that’s always moving up which creates the loop but also because no matter how slowly the user’s game is running, it will always stay in sync and move at a consistent speed.
My issue is that I have 4 different movement states that all of their own "movementRate"s and x / y sizes. When you change any value, theres a jump in where the offset is in the loop so you can see the gun position teleport around as you move between the different movement states.
I would like to somehow smooth this out but I’m not sure how I should go about it. I can switch off of my current method no problem, I just want to find a way to smoothly transition between the different movement states.
Something I’ll do is just tween between values. It sort of “normalizes” the movement by creating a bit of visual drag, but I like it since it seems more natural/human that you do the laziest-motion possible.
Basically each frame I take the Offset and lerp it 10% (accounting for delta somewhere, promise ) to the target offset.
I’ve faced this issue before as well and it has pretty elegant solution. Idea is that you have to find out the phase offset between previous argument and new one, and use that as the phase for your wave function.
local phase = 0
function changeRate(newMovementRate)
local t = tick()
local oldArgument = movementRate*t + phase
movementRate = newMovementRate
phase = oldArgument - movementRate*t
end
-- (...)
local posx = math.cos(tick()*movementRate + phase) * XSize
Smoothening out XSize and YSize is the matter of just interpolating them, those won’t cause the animation skips.