before i elaborate, i do want to point out that the entire function is ripped from GPT
this is because the math seen in this function is very confusing to me and i wouldn’t ever write it myself
feel free to mock me for it
anyway,
the camera cframe is supposed to go back to its original position always, so for example:
in automatic guns:
- the first shot sets the original camera position
- any shot afterwards will still kick the camera up, but will NOT change the original camera position
- any shot afterwards will also most likely extend the time it takes to recover, but i’ll handle that part don’t worry!!
but the issues that are present right now are:
- mouse movement is entirely restricted while the recoil recovery is in-progress, this is very bad and i do NOT want this to happen
- the camera does not kick up from any shot after shot #1, but i think this is because the recoil recovery time is faster than the recoil appliance (if that makes sense)
here’s a visual presentation of what’s going on:
and here we have the function:
local function ApplyRecoil(tool)
local camera = workspace.CurrentCamera
local recoilAngle = recoilModule[tool.Name]["VISUAL_RECOIL"]
local currentCFrame = camera.CFrame -- Capture the camera CFrame at the start of shooting
local lookVector = currentCFrame.LookVector
local upVector = Vector3.new(0, 1, 0)
local rightVector = lookVector:Cross(upVector).Unit
-- Compute the recoil rotation around the right vector (pitch adjustment)
local recoilOffset = CFrame.fromAxisAngle(rightVector, math.rad(-recoilAngle))
-- Apply the recoil offset instantly (kick the camera up)
camera.CFrame = camera.CFrame * recoilOffset
-- Smoothly return the camera back to the captured `currentCFrame`
coroutine.wrap(function()
local recoveryTime = 0.5 -- Time it takes to recover from recoil (in seconds)
local elapsedTime = 0
while elapsedTime < recoveryTime do
-- Interpolate the camera back to the original `currentCFrame`
local alpha = elapsedTime / recoveryTime
camera.CFrame = camera.CFrame:Lerp(currentCFrame, alpha)
-- Increment elapsed time and wait for the next frame
elapsedTime = elapsedTime + task.wait(0.01)
end
-- Ensure the final position is exactly the original CFrame after recovery
camera.CFrame = currentCFrame
end)()
end