Camera Shake script not performing as intended

The code for this script does work, it’s just I would like the player to be able to move the camera while it’s running. Is there anyone that can help out?

local Camera = workspace.Camera
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer

local originalCFrame = Camera.CFrame

local function applyShake(intensity, range, nonshakability, t)
    local clamp = math.clamp(1 + (intensity - 0.1)*(1-(nonshakability/range)), 0.1, intensity)
    local pos = originalCFrame.Position
    local rotX = (math.noise(t, clamp) - 0.5) * clamp / 30
    local rotY = (math.noise(t + 100, clamp) - 0.5) * clamp / 30
    local rotZ = (math.noise(t + 200, clamp) - 0.5) * clamp / 40
    Camera.CFrame = CFrame.new(pos) * CFrame.Angles(rotX, rotY, rotZ)
end

game.ReplicatedStorage.CameraShake.OnClientEvent:Connect(function(intensity, range, nonshakability, duration)
    local nonshakabilityValue = game.Workspace:FindFirstChild("NonShakability")
    if nonshakabilityValue and nonshakabilityValue:IsA("ValueBase") then
        nonshakability = nonshakabilityValue.Value
    end

    originalCFrame = Camera.CFrame 
    local startTime = os.clock()
    while os.clock() - startTime < duration do
        local t = os.clock()
        applyShake(intensity, range, nonshakability, t)
        task.wait(0.015)
    end

    local transitionDuration = 0.3
    local transitionStart = os.clock()
    local currentCFrame = Camera.CFrame
    local pos = originalCFrame.Position
    while os.clock() - transitionStart < transitionDuration do
        local alpha = (os.clock() - transitionStart) / transitionDuration
        local currentRot = currentCFrame - currentCFrame.Position
        local originalRot = originalCFrame - originalCFrame.Position
        local lerpedRot = currentRot:Lerp(originalRot, alpha)
        Camera.CFrame = CFrame.new(pos) * lerpedRot
        task.wait(0.015)
    end
    Camera.CFrame = originalCFrame
end)


You coded it to lock the user’s camera at a set position, so while the shake runs, the player can’t move or look around. Apply the shake on top of the player’s current camera instead of forcing it to an exact position.

Right now your shake script overrides the cameras CFrame every frame which is why the player cant move or rotate the camera while the shake is happening! To fix this you need to apply the shake relative to the current camera CFrame each frame, instead of storing a single originalCFrame and always resetting to it.

local Camera = workspace.CurrentCamera
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer

local function applyShake(baseCFrame, intensity, range, nonshakability, t)
    local clamp = math.clamp(1 + (intensity - 0.1) * (1 - (nonshakability / range)), 0.1, intensity)
    local rotX = (math.noise(t, clamp) - 0.5) * clamp / 30
    local rotY = (math.noise(t + 100, clamp) - 0.5) * clamp / 30
    local rotZ = (math.noise(t + 200, clamp) - 0.5) * clamp / 40
    Camera.CFrame = baseCFrame * CFrame.Angles(rotX, rotY, rotZ)
end

game.ReplicatedStorage.CameraShake.OnClientEvent:Connect(function(intensity, range, nonshakability, duration)
    local nonshakabilityValue = workspace:FindFirstChild("NonShakability")
    if nonshakabilityValue and nonshakabilityValue:IsA("ValueBase") then
        nonshakability = nonshakabilityValue.Value
    end

    local startTime = os.clock()
    while os.clock() - startTime < duration do
        local t = os.clock()
        -- apply shake relative to the cameras current frame so player can move freely
        applyShake(Camera.CFrame, intensity, range, nonshakability, t)
        task.wait(0.015)
    end
end)


Hope this helps!!