I’m making a recoil recovery system for my game, and it almost works (the camera goes down after I fire) but the problem is when its recovering, sometimes it will recover TOO much making it go past my original camera position which is not what I want. (There is also other weird bugs that happen with the camera sometimes)
Recovery:
RunService.PreRender:Connect(function()
if recoil > 0 then
currentCamera.CFrame *= CFrame.Angles(math.clamp(math.rad(-recoilTraveled), cameraRecoilStart.X, math.huge), 0, 0)
recoil = math.clamp(recoil - 0.01, 0, math.huge)
elseif recoil <= 0 then
local x, y, z = currentCamera.CFrame:ToEulerAnglesXYZ()
cameraRecoilStart = Vector3.new(x, y, z)
end
end)
Function triggering recoil:
function recoilShove()
currentCamera.CFrame = currentCamera.CFrame * CFrame.Angles(math.rad(recoil), 0, 0)
recoilTraveled = math.rad(recoil)
end
1 Like
The issue is this line (I think):
currentCamera.CFrame *= CFrame.Angles(math.clamp(math.rad(-recoilTraveled), cameraRecoilStart.X, math.huge), 0, 0)
It keeps rotating the camera every single frame and it doesn’t track how much it has already recovered and so it overshoots.
I would start by creating a variable called “recovered” to track how much it has recovered so far and stop.
Here’s the final script:
local recovered = 0
RunService.PreRender:Connect(function()
if recoil > 0 then
local step = math.min(0.01, recoil)
local angle = math.rad(step)
currentCamera.CFrame *= CFrame.Angles(-angle, 0, 0)
recovered += angle
recoil -= step
elseif recoil <= 0 then
local x, y, z = currentCamera.CFrame:ToEulerAnglesXYZ()
cameraRecoilStart = Vector3.new(x, y, z)
recoil = 0
recoilTraveled = 0
recovered = 0
end
end)
And then you can also change your recoilShove function to reset in-case it is mid recovery:
function recoilShove()
local angle = math.rad(recoil)
currentCamera.CFrame *= CFrame.Angles(angle, 0, 0)
recoilTraveled = angle
recoil = recoil
recovered = 0
end
I’m assuming recoil is a degree value.
1 Like
Thanks but I got this same answer from AI and it just makes it go back to the camera position from the most recent shot
Sorry to hear it didn’t work, yeah I guess adding a recovered variable is the simple way to think about it.
Have you tried storing the cameraRecoilStart CFrame before the recoil so it can position back?
Like this:
local recovered = 0
local recoilTraveled = 0
local cameraStartRecoil = nil
RunService.PreRender:Connect(function()
if recoil > 0 and cameraRecoilStart then
local step = math.min(0.01, recoil)
local angle = math.rad(step)
currentCamera.CFrame *= CFrame.Angles(-angle, 0, 0)
recovered += angle
recoil -= step
if recovered >= recoilTraveled then
currentCamera.CFrame = cameraRecoilStart
recoil = 0
recovered = 0
recoilTraveled = 0
cameraStartRecoil = nil
end
end
end)
And then this for the recoilShove function:
function recoilShove()
cameraRecoilStart = currentCamera.CFrame
local angle = math.rad(recoil)
currentCamera.CFrame *= CFrame.Angles(angle, 0, 0)
recoilTraveled = angle
recovered = 0
end