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:
character:SetMovementIntensity(newIntensity, newDuration)
Any guidance/assistance is greatly appreciated, thank you for taking the time to read this far, I know it’s a lot to process