how would i be able to write a gun recoil system using a spring module
well ive been trying to write a fps framework and ive run into a problem, recoil ive tried using lerp functions and looking for solutions on the dev forum, all of them were really glitchy, i have tried writing down the recoil on a seperate local script so it doesnt interfere whit the main framework
a tutorial would be helpful
--my current empty script
local repSTORE = game:GetService("ReplicatedStorage")
local isRecoiling = false
local isDamp
local camera = game.Workspace.CurrentCamera
local camearLastCf = CFrame.new()
local recoil2 = nil
local runservice = game:GetService("RunService")
local called1 = false
local called2 = false
repSTORE.Events.RecoilGun.Event:Connect(function(recoil)
called1 = false
called2 = false
recoil2 = recoil
isRecoiling = true
wait(0.1)
isRecoiling = false
end)
note that the is recoiling values are when to stop the recoil, might change that so it adds only the recoil value of the gun in the settings modules instead of doing it in a specific ammount of time
local Spring = {}
Spring.__index = Spring
function Spring.new(damping, speed)
local spring = {}
spring.position = 0
spring.velocity = 0
spring.damping = damping or 0.8
spring.speed = speed or 15
setmetatable(spring, Spring)
return spring
end
function Spring:Update(dt, targetPosition)
local acceleration = (targetPosition - self.position) * self.speed
self.velocity = (self.velocity + acceleration * dt) * self.damping
self.position = self.position + self.velocity * dt
return self.position
end
return Spring
Integration Into Recoil Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Spring = require(ReplicatedStorage:WaitForChild("Spring")) -- Assuming the module is in ReplicatedStorage
local camera = workspace.CurrentCamera
local recoilSpring = Spring.new(0.85, 15) -- Damping, Speed
local recoilAmount = 0 -- Amount of recoil to apply
local isRecoiling = false
-- Event to listen for recoil trigger (e.g., gun shot)
ReplicatedStorage.Events.RecoilGun.OnClientEvent:Connect(function(recoil)
recoilAmount = recoil -- Pass the recoil value from the server or weapon script
isRecoiling = true
end)
RunService.RenderStepped:Connect(function(dt)
if isRecoiling then
-- Update the spring with the current delta time
local recoilOffset = recoilSpring:Update(dt, recoilAmount)
-- Apply the recoil effect to the camera CFrame
camera.CFrame = camera.CFrame * CFrame.Angles(math.rad(-recoilOffset), 0, 0)
-- Stop recoiling after it has settled back
if math.abs(recoilOffset) < 0.01 then
isRecoiling = false
end
end
end)
You can adjust the recoil as needed here
Randomized example
-- For example, on a weapon fire event
local recoilValue = math.random(1, 5) -- Variable recoil amount
ReplicatedStorage.Events.RecoilGun:FireClient(player, recoilValue)