How to smoothly resize sin / cos motion?

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 :wink: ) to the target offset.

2 Likes

I’ll give that another shot. That’s what I tried a month ago and it still came out pretty jerky but it seems like in theory it should work just fine.

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.

2 Likes

Thanks I got this working more or less lol