Screenshake event not working with my first person script (Help!)

hello robloxians i’ve hit a roadblock… i’m making a day and night system and when it’s night i want a screen shake to play but it just doesn’t it’s all mainly scripts no animations so i’ll give them below, it works in third person without my custom camera script but when i have the custom camera script enabled it just doesn’t want to work which is weird because it lets the camera wobble with my running script :confused: i left comments on my scripts for so it’s hopefully less confusing for y’all cuz i’m messy at this lol

my local script custom camera script in starter gui:

-- Define a separate scope for the camera control script
do
	wait(2)

	-- Services and Player/Character Variables
	local InputService = game:GetService("UserInputService")
	local RunService = game:GetService("RunService")
	local Camera = game.Workspace.CurrentCamera
	local Player = game.Players.LocalPlayer
	local Character = Player.Character or Player.CharacterAdded:Wait()
	local Head = Character:WaitForChild("Head")
	local Torso = Character:WaitForChild("Torso")
	local RootPart = Character:WaitForChild("HumanoidRootPart")
	local RootJoint = RootPart.RootJoint
	local Neck = Torso.Neck

	-- Initial Camera Settings
	Camera.FieldOfView = 90
	Camera.CameraType = "Scriptable"
	InputService.MouseBehavior = Enum.MouseBehavior.LockCenter

	-- Helper Functions
	local v3 = Vector3.new
	local cf = CFrame.new
	local inverse = cf().inverse
	local fromAxisAngle = CFrame.fromAxisAngle
	local atan, atan2 = math.atan, math.atan2
	local acos = math.acos

	local function toAxisAngleFromVector(v)
		local z = v.z
		return z*z < 0.99999 and v3(v.y, -v.x, 0).unit * acos(-z) or v3()
	end

	local function AxisAngleLookOrientation(c, v, t) -- CFrame, Vector, Tween
		local c = c - c.p
		local rv = (inverse(c) * v).unit
		local rz = rv.z
		return rz*rz < 0.99999 and c * fromAxisAngle(v3(rv.y, -rv.x, 0), acos(-rz) * (t or 1)) or c
	end

	local function AxisAngleLookNew(v, t) -- CFrame, Vector, Tween
		local rv = v.unit
		local rz = rv.z
		return rz*rz < 0.99999 and fromAxisAngle(v3(rv.y, -rv.x, 0), acos(-rz) * (t or 1)) or cf()
	end

	local function AxisAngleLook(c, v, t) -- CFrame, Vector, Tween
		local rv = (inverse(c) * v).unit
		local rz = rv.z
		return rz*rz < 0.99999 and c * fromAxisAngle(v3(rv.y, -rv.x, 0), acos(-rz) * (t or 1)) or c
	end

	-- Sensitivity and Initial Camera Direction
	local Sensitivity = 0.005
	local CameraDirection = Vector3.new(0, 0, 1)

	-- Euler Angle Calculations
	local function EulerAnglesYX(l)
		local x, z = l.x, l.z
		return atan(l.y / (x*x + z*z)^0.5), -atan2(l.x, -z)
	end

	local function AnglesXY(l)
		local z = l.z
		return atan2(l.y, -z), -atan2(l.x, -z)
	end

	-- Mouse Movement Handling
	local function MouseMoved(Input)
		if Input.UserInputType == Enum.UserInputType.MouseMovement then
			local dx, dy = Input.Delta.x * Sensitivity, Input.Delta.y * Sensitivity
			local m2 = dx*dx + dy*dy
			if m2 > 0 then
				CameraDirection = (AxisAngleLookOrientation(RootPart.CFrame, CameraDirection) * fromAxisAngle(v3(-dy, -dx, 0), m2^0.5)).lookVector
			end
			local RootOrientation = RootPart.CFrame - RootPart.Position
			local RelativeDirection = RootOrientation:inverse() * CameraDirection
			local AngX, AngY = AnglesXY(RelativeDirection)
			if AngX < -1.57 * 11 / 12 then
				local y, z, c, s = RelativeDirection.y, RelativeDirection.z, math.cos(-1.57 * 11 / 12 - AngX), -math.sin(-1.57 * 11 / 12 - AngX)
				z, y = z * c - y * s, z * s + y * c
				CameraDirection = RootOrientation * v3(RelativeDirection.x < 0 and -(1 - y*y - z*z)^0.5 or (1 - y*y - z*z)^0.5, y, z)
			elseif AngX > 1.57 * 11 / 12 then
				local y, z, c, s = RelativeDirection.y, RelativeDirection.z, math.cos(1.57 * 11 / 12 - AngX), -math.sin(1.57 * 11 / 12 - AngX)
				z, y = z * c - y * s, z * s + y * c
				CameraDirection = RootOrientation * v3(RelativeDirection.x < 0 and -(1 - y*y - z*z)^0.5 or (1 - y*y - z*z)^0.5, y, z)
			end
		end
	end

	-- Connect MouseMoved only once
	local mouseMovedConnection = InputService.InputChanged:Connect(MouseMoved)

	Neck.C1 = cf()

	-- Direction Bound and Current Angle Variables
	local _
	local DirectionBound = 3.14159 / 3
	local CurrentAngY = 0

	local cameraOverride = nil -- New variable to hold the camera override function

	-- Camera Update Function
	local function CameraUpdate(deltaTime)
		if cameraOverride then
			cameraOverride(deltaTime)
			return
		end

		Camera.CameraType = "Scriptable"
		local cx, cz = CameraDirection.x, CameraDirection.z
		local rvx, rvz = RootPart.Velocity.x, RootPart.Velocity.z
		if rvx*rvx + rvz*rvz > 4 and cx*rvx + cz*rvz < -0.5 * (cx*cx + cz*cz)^0.5 * (rvx*rvx + rvz*rvz)^0.5 then
			DirectionBound = math.min(DirectionBound * 0.9, math.abs(CurrentAngY * 0.9))
		else
			DirectionBound = DirectionBound * 0.1 + 3.14159 / 3 * 0.9
		end
		local AngX, AngY = EulerAnglesYX((RootPart.CFrame - RootPart.Position):inverse() * CameraDirection)
		if AngY > DirectionBound then
			RootPart.CFrame = RootPart.CFrame * CFrame.Angles(0, AngY - DirectionBound, 0)
		elseif AngY < -DirectionBound then
			RootPart.CFrame = RootPart.CFrame * CFrame.Angles(0, AngY + DirectionBound, 0)
		end
		_, CurrentAngY = EulerAnglesYX((RootPart.CFrame - RootPart.Position):inverse() * CameraDirection)
		local CameraOrientation = AxisAngleLookNew((RootPart.CFrame - RootPart.Position):inverse() * CameraDirection, 1)
		Neck.C0 = CFrame.new(0, 1, 0) * CameraOrientation * CFrame.new(0, 0.5, 0)

		-- Camera Positioning
		local PreCam = AxisAngleLook(RootPart.CFrame * cf(0, 1, 0), RootPart.CFrame * v3(0, 1, 0) + CameraDirection) * CFrame.new(0, 0.825, 0)
		local Zoom = -0.5
		Camera.CoordinateFrame = PreCam * CFrame.new(0, 0, Zoom)
	end

	-- Connect Camera Update to RenderStepped
	RunService.RenderStepped:Connect(CameraUpdate)

	-- Handle Window Focus Gained
	local function OnFocusGained()
		-- Ensure the event is connected only once
		if mouseMovedConnection.Connected then
			mouseMovedConnection:Disconnect()
		end
		mouseMovedConnection = InputService.InputChanged:Connect(MouseMoved)
		-- Reapply settings if needed
		InputService.MouseBehavior = Enum.MouseBehavior.LockCenter
	end

	InputService.WindowFocused:Connect(OnFocusGained)

	-- Function to set camera override (new)
	function setCameraOverride(overrideFunction)
		cameraOverride = overrideFunction
	end
end

here is the script in serverscriptstorage (to manually change the times yourself make sure to change the userid part)

local Lighting = game:GetService("Lighting")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Create RemoteEvent
local nightEvent = ReplicatedStorage:FindFirstChild("NightEvent") or Instance.new("RemoteEvent", ReplicatedStorage)
nightEvent.Name = "NightEvent"

local dayDuration = 180 -- 3 minutes
local nightDuration = 900 -- 15 minutes
local fadeDuration = 10 -- Duration for smooth transition

local playerID = 321994668

-- Add or find existing day and night sounds
local daySound = Lighting:FindFirstChild("DayAmbience") or Instance.new("Sound", Lighting)
daySound.SoundId = "rbxassetid://138089070"
daySound.Looped = true
daySound.Volume = 0
daySound.Name = "DayAmbience"
daySound:Play()

local nightSound = Lighting:FindFirstChild("NightAmbience") or Instance.new("Sound", Lighting)
nightSound.SoundId = "rbxassetid://390457804"
nightSound.Looped = true
nightSound.Volume = 0
nightSound.Name = "NightAmbience"
nightSound:Play()

local intoNightSound = Lighting:FindFirstChild("IntoNight") or Instance.new("Sound", Lighting)
intoNightSound.SoundId = "rbxassetid://13061809"
intoNightSound.Looped = false
intoNightSound.Volume = 1
intoNightSound.PlaybackSpeed = 0.2
intoNightSound.Name = "IntoNight"

local itsNightSound = Lighting:FindFirstChild("ItsNight") or Instance.new("Sound", Lighting)
itsNightSound.SoundId = "rbxassetid://9043340747"
itsNightSound.Looped = false
itsNightSound.Volume = 1
itsNightSound.Name = "ItsNight"

print("Day sound, night sound, into night sound, and its night sound initialized and started.")

-- Function to smoothly change the lighting and audio
local function smoothTransition(targetBrightness, targetAmbient, targetOutdoorAmbient, targetClockTime, targetDayVolume, targetNightVolume, playIntoNight, duration)
	local initialBrightness = Lighting.Brightness
	local initialAmbient = Lighting.Ambient
	local initialOutdoorAmbient = Lighting.OutdoorAmbient
	local initialClockTime = Lighting.ClockTime
	local initialDayVolume = daySound.Volume
	local initialNightVolume = nightSound.Volume
	local startTime = tick()

	-- Restart and delay playing into night sound by 0.5 seconds
	if playIntoNight then
		intoNightSound:Stop()
		intoNightSound.TimePosition = 0
		intoNightSound.Volume = 1
		intoNightSound.PlaybackSpeed = 0.2
		spawn(function()
			wait(0.5)
			print("Playing into night sound.")
			intoNightSound:Play()
		end)
	end

	while tick() - startTime < duration do
		local elapsed = tick() - startTime
		local progress = elapsed / duration

		-- Update lighting properties
		Lighting.Brightness = initialBrightness + (targetBrightness - initialBrightness) * progress
		Lighting.Ambient = initialAmbient:lerp(targetAmbient, progress)
		Lighting.OutdoorAmbient = initialOutdoorAmbient:lerp(targetOutdoorAmbient, progress)
		Lighting.ClockTime = initialClockTime + (targetClockTime - initialClockTime) * progress

		-- Update audio volumes
		daySound.Volume = initialDayVolume + (targetDayVolume - initialDayVolume) * progress
		nightSound.Volume = initialNightVolume + (targetNightVolume - initialNightVolume) * progress

		-- Fade out into night sound near the end
		if playIntoNight and intoNightSound.IsPlaying and elapsed > duration - 1 then
			intoNightSound.Volume = (duration - elapsed) / 1
		end

		-- Wait a short time before the next update
		wait(0.03) -- Update more frequently for smoother transition
	end

	-- Ensure final values are set
	Lighting.Brightness = targetBrightness
	Lighting.Ambient = targetAmbient
	Lighting.OutdoorAmbient = targetOutdoorAmbient
	Lighting.ClockTime = targetClockTime
	daySound.Volume = targetDayVolume
	nightSound.Volume = targetNightVolume
	if playIntoNight then
		intoNightSound.Volume = 0
		print("Transition completed: ClockTime =", targetClockTime, "Day Volume =", targetDayVolume, "Night Volume =", targetNightVolume)
		print("It's night now.")
		wait(1)
		itsNightSound:Play()
		nightEvent:FireAllClients()  -- Fire the event to all clients
	end
end

-- Function to start the day-night cycle
local function startDayNightCycle()
	while true do
		-- Daytime (6 AM to 6 PM)
		print("Starting daytime transition.")
		smoothTransition(2, Color3.fromRGB(255, 255, 255), Color3.fromRGB(128, 128, 128), 14, 0.207, 0, false, fadeDuration)
		wait(dayDuration)

		-- Transition to night (6 PM to 6 AM)
		print("Starting night transition.")
		smoothTransition(0, Color3.fromRGB(0, 0, 0), Color3.fromRGB(0, 0, 0), 0, 0, 0.207, true, fadeDuration)
		wait(nightDuration)
	end
end

-- Function to handle manual triggering of day and night
local function onChatMessage(player, message)
	if player.UserId == playerID then
		if message == ";trigger day" then
			print("Manual trigger: day")
			smoothTransition(2, Color3.fromRGB(255, 255, 255), Color3.fromRGB(128, 128, 128), 14, 0.207, 0, false, fadeDuration)
		elseif message == ";trigger night" then
			print("Manual trigger: night")
			smoothTransition(0, Color3.fromRGB(0, 0, 0), Color3.fromRGB(0, 0, 0), 0, 0, 0.207, true, fadeDuration)
		end
	end
end

-- Connect the chat event
Players.PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(message)
		onChatMessage(player, message)
	end)
end)

-- Start the day-night cycle
coroutine.wrap(startDayNightCycle)()

here is the local script night start effect in startercharacter scripts:

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

-- Create or get the RemoteEvent
local nightEvent = ReplicatedStorage:WaitForChild("NightEvent")

-- Function to handle camera shake
local function cameraShake(duration, intensity)
    local startTime = tick()
    local originalCFrame = Camera.CFrame

    local function updateCameraShake()
        local elapsed = tick() - startTime
        if elapsed >= duration then
            RunService:UnbindFromRenderStep("CameraShake")
            Camera.CFrame = originalCFrame
            return
        end

        local offset = CFrame.new(
            math.random(-intensity, intensity) / 100,
            math.random(-intensity, intensity) / 100,
            math.random(-intensity, intensity) / 100
        )
        Camera.CFrame = originalCFrame * offset
    end

    RunService:BindToRenderStep("CameraShake", Enum.RenderPriority.Camera.Value + 1, updateCameraShake)
end

-- Event listener for night event
nightEvent.OnClientEvent:Connect(function()
    cameraShake(2, 0.5)  -- Shake the camera for 2 seconds with intensity 0.5
end)

I greatly appreciate any help people give! :slight_smile:

Id also be happy to give you the script that it works on for movement wise, just message(PM) me because i worked hard in it and it’s rather advanced.(to me atleast lol)

math.random(param1,param2) only works with integers (in your case, its only returning 0)

id recommend doing something like

(math.random() * 2 - 1) * intensity

… or perhaps in some more elegant way that i don’t know of
(not specifying any parameters gives you a random float between 0-1)

1 Like

well now im not sure i changed it with still the same issue so im now kind of at a loss :confused:

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

-- Get the RemoteEvent
local nightEvent = ReplicatedStorage:WaitForChild("NightEvent")

-- Function to handle camera shake
local function cameraShake(duration, intensity)
    local startTime = tick()
    local originalCFrame = Camera.CFrame

    local function updateCameraShake()
        local elapsed = tick() - startTime
        if elapsed >= duration then
            RunService:UnbindFromRenderStep("CameraShake")
            Camera.CFrame = originalCFrame
            return
        end

        -- Generate smooth random offsets using math.noise
        local shakeX = (math.noise(elapsed * 10) * 2 - 1) * intensity
        local shakeY = (math.noise(elapsed * 10 + 100) * 2 - 1) * intensity
        local shakeZ = (math.noise(elapsed * 10 + 200) * 2 - 1) * intensity

        local offset = CFrame.new(shakeX, shakeY, shakeZ)
        Camera.CFrame = originalCFrame * offset
    end

    RunService:BindToRenderStep("CameraShake", Enum.RenderPriority.Camera.Value + 1, updateCameraShake)
end

-- Event listener for night event
nightEvent.OnClientEvent:Connect(function()
    cameraShake(2, 0.5)  -- Shake the camera for 2 seconds with intensity 0.5
end)

i used a different method and still the same issue.

I FOUND IT OUT HERE FOR ANYONE WHO EVER HAS THE SAME ISSUE :smiley:
just tweak the camera shake how you see fit

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

-- Get the RemoteEvent
local nightEvent = ReplicatedStorage:WaitForChild("NightEvent")

-- Variables for camera shake effect
local shakeDuration = 0
local shakeIntensity = 0
local shakeStartTime = 0

-- Function to handle camera shake
local function startCameraShake(duration, intensity)
	shakeDuration = duration
	shakeIntensity = intensity
	shakeStartTime = tick()
end

-- Camera shake effect function
local function cameraShakeEffect(deltaTime)
	if tick() - shakeStartTime <= shakeDuration then
		local elapsed = tick() - shakeStartTime

		-- Generate smooth random offsets using math.noise
		local shakeX = (math.noise(elapsed * 10) * 2 - 1) * shakeIntensity
		local shakeY = (math.noise(elapsed * 10 + 100) * 2 - 1) * shakeIntensity
		local shakeZ = (math.noise(elapsed * 10 + 200) * 2 - 1) * shakeIntensity

		local offset = CFrame.new(shakeX, shakeY, shakeZ)
		Camera.CFrame = Camera.CFrame * offset
	end
end

-- Event listener for night event
nightEvent.OnClientEvent:Connect(function()
	startCameraShake(2, 0.5)  -- Shake the camera for 2 seconds with intensity 0.5
end)

-- Main camera effect
RunService.RenderStepped:Connect(function(deltaTime)
	cameraShakeEffect(deltaTime)
end)
1 Like

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