Keywords that you might not know because they’re system specific:
MovementIntensity: How wide of an arc the “Figure eight” has.
MoveDuration: How long it takes the animation method to complete the figure eight.
I’ve created an FPS where the arms/guns are connected to a central part, which is placed at the center of the camera, and then moved dynamically to create that little shake movement when you walk or sprint.
The animation is rougly a sideways figure 8 that I created using sine waves, but getting smooth interpolation between different intensity’s and durations of animations has presented a challenge for me, as I’m not incredible at math, but i can get by.
Right now, I have a series of static “Walk Styles” that have predetermined Movement intensity’s and durations. As I add accelerated movement and walkspeeds, it makes the system feel very cheap, so I use static walkspeeds.
This is the method that handles the “breathing” effect, as I call it.
function character:StartBreathing() spawn(function() local renderstepped = game:GetService('RunService').RenderStepped local AnimTime = 2.3 local lastTick = tick() local PercentPosition = 0 character.Properties.isBreathing = true local lastpercent = PercentPosition local laststep = 0 while renderstepped:wait() do character.Properties.Walkspeed:update() game.Players.LocalPlayer.Character:FindFirstChild("Humanoid").WalkSpeed = character.Properties.Walkspeed.position if character.Properties.Speed >= 1 then if (tick() - laststep) > 10/character.Properties.Speed then character:FootStep() laststep = tick() end end local ElapsedTime = (tick() - lastTick)/(character.Properties.MoveDuration * AnimTime) lastTick = tick() PercentPosition = PercentPosition + ElapsedTime local x = math.sin(math.rad((PercentPosition) * 360)) * 4 local y = math.sin(math.rad((PercentPosition * 2) * 360)) * 4 character.Properties.NeckOffset = CFrame.new(math.rad(x*character.Properties.MoveIntensity),math.rad(y*character.Properties.MoveIntensity),0) camera.Properties.ShakeOffset = CFrame.new() * CFrame.Angles(-math.rad((y*character.Properties.MoveIntensity)/7),-math.rad((x*character.Properties.MoveIntensity)/15),0) lastpercent = PercentPosition if PercentPosition >= 1 then PercentPosition = 0 end if not character.Properties.isBreathing or not game.Players.LocalPlayer.Character then break end end end) end
and this is the event that calls the method that interpolates the Duration and Intensity
character.Running = game.Players.LocalPlayer.Character:WaitForChild('Humanoid').Running:connect(function(S) local State = game.Players.LocalPlayer.Character.Humanoid:GetState() character.Properties.Speed = S if State ~= Enum.HumanoidStateType.Jumping and State ~= Enum.HumanoidStateType.Freefall and State ~= Enum.HumanoidStateType.FallingDown then if (S >= 1) and (S <= 10) and character.Properties.walkStyle ~= 'Slow' and not character.State.Wallrunning and not character.State.Aiming then character.Properties.walkStyle = 'Slow' character:SetMovementIntensity(.2,4) elseif (S > 10) and (S <= 26) and character.Properties.walkStyle ~= 'Walk' and not character.State.Sprinting and not character.State.Wallrunning and not character.State.Aiming then character.Properties.walkStyle = 'Walk' character:SetMovementIntensity(.6,.5) elseif S > 19 and character.Properties.walkStyle ~= 'Sprint' and character.State.Sprinting then character.Properties.walkStyle = 'Sprint' character:SetMovementIntensity(1.8,.35) elseif (S < 1) and character.Properties.walkStyle ~= 'Stopped' and not character.State.Aiming and not character.State.Wallrunning then character.Properties.walkStyle = 'Stopped' character:SetMovementIntensity(.2,4) elseif (S >= 1) and (S <= 10) and character.Properties.walkStyle ~= 'AimSlow' and not character.State.Wallrunning and character.State.Aiming then character.Properties.walkStyle = 'AimSlow' character:SetMovementIntensity(.03,4) elseif (S < 1) and character.Properties.walkStyle ~= "AimStopped" and character.State.Aiming and not character.State.Wallrunning then character.Properties.walkStyle = 'AimStopped' character:SetMovementIntensity(.01,4) end else --character:SetMovementIntensity(.2,4) end end)
I’d like to move away from this incredibly static method, but I’m not sure where to begin. I can provide the SetMovementIntensity method if you need it, but it essentially just performs a linear interpolation between the old and new intensity’s/durations. It is called like this:
Any guidance/assistance is greatly appreciated, thank you for taking the time to read this far, I know it’s a lot to process