Script for camera shake upon music play doesn't work

I’m scripting an SCP 682 event where as when the creature roars, the camera shakes. I also want it when an explosion happens during the same event the camera shakes also. Problem about this script I found off of toolbox is that you can’t have multiple sounds shake the camera. Only one can. Attempting to fix this issue, I added a table so that the Music variable had 3 sounds with it, so it had the ability to play all 3 sounds and have the camera shake in each in every one. However, this method does not work for some reason and I am very confused.

Code

local RunService = game:GetService("RunService")
local CurrentCamera = workspace.CurrentCamera

--Music locations
local Music1 = workspace.ServerEvents["Breach-Related"].Breach682.Crash1
local Music2 = workspace.ServerEvents["Breach-Related"].Breach682.Crash2
local Music3 = workspace.ServerEvents["Breach-Related"].Breach682.Roar

--RemoteEvents
local Crash1 = game.ReplicatedStorage.Screenshake_ApacheCrash1
local Crash2 = game.ReplicatedStorage.Screenshake_ApacheCrash2
local Roar = game.ReplicatedStorage.Roar

--Table
local Music = {};
table.insert(Music, workspace.ServerEvents["Breach-Related"].Breach682.Crash1);
table.insert(Music, workspace.ServerEvents["Breach-Related"].Breach682.Crash2);
table.insert(Music, workspace.ServerEvents["Breach-Related"].Breach682.Roar);

--When the RemoteEvents are activated the music plays 
Crash1.OnClientEvent:Connect(function()
	Music1:Play()
end)

Crash2.OnClientEvent:Connect(function()
	Music2:Play()
end)

Roar.OnClientEvent:Connect(function()
	Music3:Play()
end)

local ScreenShakeSettings = {
	CameraMinFOV = 75,
	CameraMaxFOV = 100,
	CameraMaxVolume = 750
}

-- When the sounds play the screen shakes
game:GetService("RunService").RenderStepped:connect(function()
	local CurrentLoudness = Music.PlaybackLoudness
	local FOV = ScreenShakeSettings.CameraMinFOV + (ScreenShakeSettings.CameraMaxFOV - ScreenShakeSettings.CameraMinFOV) * (CurrentLoudness / ScreenShakeSettings.CameraMaxVolume)
	if FOV > 0 and FOV < 130 then
		CurrentCamera.FieldOfView = FOV
	end
end)

image

1 Like

I’ve modified it and i did found some issues
Try it:

local RunService = game:GetService("RunService")
local CurrentCamera = workspace.CurrentCamera

-- Music locations
local Music1 = workspace.ServerEvents["Breach-Related"].Breach682.Crash1
local Music2 = workspace.ServerEvents["Breach-Related"].Breach682.Crash2
local Music3 = workspace.ServerEvents["Breach-Related"].Breach682.Roar

-- RemoteEvents
local Crash1 = game.ReplicatedStorage.Screenshake_ApacheCrash1
local Crash2 = game.ReplicatedStorage.Screenshake_ApacheCrash2
local Roar = game.ReplicatedStorage.Roar

-- Table
local Music = {
	Music1,
	Music2,
	Music3
}

-- When the RemoteEvents are activated, the music plays
Crash1.OnClientEvent:Connect(function()
	Music1:Play()
	StartScreenShake()
end)

Crash2.OnClientEvent:Connect(function()
	Music2:Play()
	StartScreenShake()
end)

Roar.OnClientEvent:Connect(function()
	Music3:Play()
	StartScreenShake()
end)

local ScreenShakeSettings = {
	CameraMinFOV = 75,
	CameraMaxFOV = 100,
	CameraMaxVolume = 750
}

local function StartScreenShake()
	local initialFOV = CurrentCamera.FieldOfView
	local initialTime = tick()
	local duration = 0.2 -- Adjust this value to control the duration of the screen shake

	RunService:BindToRenderStep("ScreenShake", Enum.RenderPriority.Camera.Value, function()
		local currentTime = tick()
		local elapsedTime = currentTime - initialTime

		if elapsedTime >= duration then
			CurrentCamera.FieldOfView = initialFOV -- Reset the camera FOV to its initial value
			RunService:UnbindFromRenderStep("ScreenShake")
		else
			local progress = elapsedTime / duration
			local shakeIntensity = 1 - progress
			local FOV = ScreenShakeSettings.CameraMinFOV + (ScreenShakeSettings.CameraMaxFOV - ScreenShakeSettings.CameraMinFOV) * shakeIntensity
			
			if FOV > 0 and FOV < 130 then
				CurrentCamera.FieldOfView = FOV
			end
		end
	end)
end

So what i did is i added a StartScreenShake() function that handles the camera shake effect.
And RunService:BindToRenderStep() to continuously update the camera FOV based on the elapsed time.
Plus i necessarily modified the event handlers for Crash1, Crash2, and Roar RemoteEvents to call the StartScreenShake() function after playing the music.

1 Like

I tried this, and I feel this is 100% a step in the right direction, but whenever the time comes for the camera to begin shaking this error pops up:


(Crash2 is the script name)

Hmm,i guess we just change it a little bit
Here’s an updated version of the script:

local RunService = game:GetService("RunService")
local CurrentCamera = workspace.CurrentCamera

local Music1 = workspace.ServerEvents["Breach-Related"].Breach682.Crash1
local Music2 = workspace.ServerEvents["Breach-Related"].Breach682.Crash2
local Music3 = workspace.ServerEvents["Breach-Related"].Breach682.Roar

local Crash1 = game.ReplicatedStorage.Screenshake_ApacheCrash1
local Crash2 = game.ReplicatedStorage.Screenshake_ApacheCrash2
local Roar = game.ReplicatedStorage.Roar

local Music = {
    Crash1 = Music1,
    Crash2 = Music2,
    Roar = Music3
}

local ScreenShakeSettings = {
    CameraMinFOV = 75,
    CameraMaxFOV = 100,
    CameraMaxVolume = 750
}

local function StartScreenShake()
    local initialFOV = CurrentCamera.FieldOfView
    local initialTime = tick()
    local duration = 0.2 -- Adjust this value to control the duration of the screen shake

    RunService:BindToRenderStep("ScreenShake", Enum.RenderPriority.Camera.Value, function()
        local currentTime = tick()
        local elapsedTime = currentTime - initialTime

        if elapsedTime >= duration then
            CurrentCamera.FieldOfView = initialFOV -- Reset the camera FOV to its initial value
            RunService:UnbindFromRenderStep("ScreenShake")
        else
            local progress = elapsedTime / duration
            local shakeIntensity = 1 - progress
            local FOV = ScreenShakeSettings.CameraMinFOV + (ScreenShakeSettings.CameraMaxFOV - ScreenShakeSettings.CameraMinFOV) * shakeIntensity

            if FOV > 0 and FOV < 130 then
                CurrentCamera.FieldOfView = FOV
            end
        end
    end)
end

local function PlayMusicAndShake(event)
    local music = Music[event.Name]
    if music then
        music:Play()
        StartScreenShake()
    end
end

Crash1.OnClientEvent:Connect(PlayMusicAndShake)
Crash2.OnClientEvent:Connect(PlayMusicAndShake)
Roar.OnClientEvent:Connect(PlayMusicAndShake)

What I’ve done is created a reusable function PlayMusicAndShake to handle playing the music and triggering the screen shake. This function checks if the event name exists in the Music table before playing the music and starting the screen shake.And moved the StartScreenShake function above the RemoteEvent connections to ensure it is defined before being called.

These improvements should help streamline the code and make it more maintainable. Remember to adjust the duration value in the StartScreenShake function to control the duration of the screen shake effect.

Script stops at line 49 due to this error:


image
Music doesn’t play, nor does the screen shake due to this error.

I see…
Here’s another version of the script:

local RunService = game:GetService("RunService")
local CurrentCamera = workspace.CurrentCamera

local Music1 = workspace.ServerEvents["Breach-Related"] and workspace.ServerEvents["Breach-Related"].Breach682 and workspace.ServerEvents["Breach-Related"].Breach682.Crash1
local Music2 = workspace.ServerEvents["Breach-Related"] and workspace.ServerEvents["Breach-Related"].Breach682 and workspace.ServerEvents["Breach-Related"].Breach682.Crash2
local Music3 = workspace.ServerEvents["Breach-Related"] and workspace.ServerEvents["Breach-Related"].Breach682 and workspace.ServerEvents["Breach-Related"].Breach682.Roar

local Crash1 = game.ReplicatedStorage.Screenshake_ApacheCrash1
local Crash2 = game.ReplicatedStorage.Screenshake_ApacheCrash2
local Roar = game.ReplicatedStorage.Roar

local Music = {
    Crash1 = Music1,
    Crash2 = Music2,
    Roar = Music3
}

local ScreenShakeSettings = {
    CameraMinFOV = 75,
    CameraMaxFOV = 100,
    CameraMaxVolume = 750
}

local function StartScreenShake()
    local initialFOV = CurrentCamera.FieldOfView
    local initialTime = tick()
    local duration = 0.2 -- Adjust this value to control the duration of the screen shake

    RunService:BindToRenderStep("ScreenShake", Enum.RenderPriority.Camera.Value, function()
        local currentTime = tick()
        local elapsedTime = currentTime - initialTime

        if elapsedTime >= duration then
            CurrentCamera.FieldOfView = initialFOV -- Reset the camera FOV to its initial value
            RunService:UnbindFromRenderStep("ScreenShake")
        else
            local progress = elapsedTime / duration
            local shakeIntensity = 1 - progress
            local FOV = ScreenShakeSettings.CameraMinFOV + (ScreenShakeSettings.CameraMaxFOV - ScreenShakeSettings.CameraMinFOV) * shakeIntensity

            if FOV > 0 and FOV < 130 then
                CurrentCamera.FieldOfView = FOV
            end
        end
    end)
end

local function PlayMusicAndShake(event)
    local music = Music[event.Name]
    if music then
        music:Play()
        StartScreenShake()
    end
end

Crash1.OnClientEvent:Connect(PlayMusicAndShake)
Crash2.OnClientEvent:Connect(PlayMusicAndShake)
Roar.OnClientEvent:Connect(PlayMusicAndShake)

This time i added checks to ensure that the workspace.ServerEvents["Breach-Related"].Breach682 object exists before attempting to access its properties. This prevents the script from throwing an error if any of those objects are nil

the checks don’t solve the issue as the problem still persists. "Attempt to index nil with ‘Name’


image

Again:

local RunService = game:GetService("RunService")
local CurrentCamera = workspace.CurrentCamera

local function getMusic(eventName)
    local success, music = pcall(function()
        return workspace.ServerEvents["Breach-Related"].Breach682[eventName]
    end)
    if success then
        return music
    else
        warn("Failed to retrieve music for event: " .. eventName)
        return nil
    end
end

local Crash1 = game.ReplicatedStorage.Screenshake_ApacheCrash1
local Crash2 = game.ReplicatedStorage.Screenshake_ApacheCrash2
local Roar = game.ReplicatedStorage.Roar

local Music = {
    Crash1 = getMusic("Crash1"),
    Crash2 = getMusic("Crash2"),
    Roar = getMusic("Roar")
}

local ScreenShakeSettings = {
    CameraMinFOV = 75,
    CameraMaxFOV = 100,
    CameraMaxVolume = 750
}

local function StartScreenShake()
    local initialFOV = CurrentCamera.FieldOfView
    local initialTime = tick()
    local duration = 0.2 -- Adjust this value to control the duration of the screen shake

    RunService:BindToRenderStep("ScreenShake", Enum.RenderPriority.Camera.Value, function()
        local currentTime = tick()
        local elapsedTime = currentTime - initialTime

        if elapsedTime >= duration then
            CurrentCamera.FieldOfView = initialFOV -- Reset the camera FOV to its initial value
            RunService:UnbindFromRenderStep("ScreenShake")
        else
            local progress = elapsedTime / duration
            local shakeIntensity = 1 - progress
            local FOV = ScreenShakeSettings.CameraMinFOV + (ScreenShakeSettings.CameraMaxFOV - ScreenShakeSettings.CameraMinFOV) * shakeIntensity

            if FOV > 0 and FOV < 130 then
                CurrentCamera.FieldOfView = FOV
            end
        end
    end)
end

local function PlayMusicAndShake(eventName)
    local music = Music[eventName]
    if music then
        music:Play()
        StartScreenShake()
    end
end

Crash1.OnClientEvent:Connect(function()
    PlayMusicAndShake("Crash1")
end)

Crash2.OnClientEvent:Connect(function()
    PlayMusicAndShake("Crash2")
end)

Roar.OnClientEvent:Connect(function()
    PlayMusicAndShake("Roar")
end)

I added a function called getMusic that uses pcall to handle any potential errors that may occur when accessing the music properties. If an error occurs, it will display a warning in the output and return nil. This way, the script continues running even if some music properties are not available.
The issue is occurring because the OnClientEvent signal passes an argument that doesn’t have a Name property. so line 49 turned into:

local function PlayMusicAndShake(eventName)
    local music = Music[eventName]
    if music then
        music:Play()
        StartScreenShake()

Script works! Thank you for your patience!

No problem :wink:
It’s been an honor to serve with you

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.