In this script, I run a script with RunService, which will continuously call the function: playShake, but the problem is that playShake has a wait time that is disrupted because of RunService.
local function setInfo(goal: number)
local brightness_goal = goal * MAX_BRIGHTNESS
local contrast_goal = goal * MAX_CONTRAST
local color_goal = 255 * (1 - goal)
local shake_intensity_goal = goal * MAX_SHAKE_INTENSITY
local shake_speed_goal = goal * MAX_SHAKE_SPEED
colorCorrection.Brightness = brightness_goal
colorCorrection.Contrast = contrast_goal
colorCorrection.TintColor = Color3.fromRGB(255, color_goal, color_goal)
ShakeCamera:playShake(shake_intensity_goal) -- with runService this function is playing but this function get time....
end
local player = game.Players.LocalPlayer
local character = player.Character
local humanoid = character.Humanoid:: Humanoid
--libs
local VECTOR_3 = Vector3.new
local MATH_RANDOM = math.random
local ShakeCamera = {}
function ShakeCamera:playShake(shakeIntensity: number): ()
local shakeOffset = Vector3.new(
MATH_RANDOM(-shakeIntensity, shakeIntensity),
MATH_RANDOM(-shakeIntensity, shakeIntensity),
MATH_RANDOM(-shakeIntensity, shakeIntensity)
)
local originalOffset = VECTOR_3(0, 0, 0)
humanoid.CameraOffset = originalOffset + shakeOffset
task.wait(2) -- i add 2 for exemple
humanoid.CameraOffset = originalOffset
end
return ShakeCamera
task.delay runs without throttling the current thread and should allow it to continue running around it, my mistake though, i tested the script myself and if you passed the DeltaTime into the function and added that to the delay it seems to work fine for me.
if not game:IsLoaded() then game.Loaded:Wait() end
--SERVICE
local RunService = game:GetService("RunService")
local ReplicatedStorage = game.ReplicatedStorage
local Lighting = game:GetService("Lighting")
--MODULES
local ShakeCamera = require(ReplicatedStorage.Camera.ShakeCamera)
--PLAYER
local player = game.Players.LocalPlayer
local character = player.Character
local humanoidRootPart = character.HumanoidRootPart:: BasePart
local humanoid = character.Humanoid:: Humanoid
--LIGHTING
local colorCorrection = Lighting.ColorCorrection
--WORKSCPACE
local Build = workspace:WaitForChild("Build")
local secretPart = Build:FindFirstChild("SecretPart")
--NOT CHANGE VALUE
local MIN_DISTANCE = 50
local MAX_DISTANCE = 15
local MAX_BRIGHTNESS = -0.8
local MAX_CONTRAST = 1
local MAX_SHAKE_SPEED = 2
local MAX_SHAKE_INTENSITY = 1.5
--CONNECTION
local heatbeatConnection
local heartbeatFunction
local function resetEffects()
colorCorrection.Brightness = 0
colorCorrection.Contrast = 0
colorCorrection.TintColor = Color3.fromRGB(255, 255, 255)
end
local function setEffects(goal: number)
local brightness_goal = goal * MAX_BRIGHTNESS
local contrast_goal = goal * MAX_CONTRAST
local color_goal = 255 * (1 - goal)
local shake_intensity_goal = goal * MAX_SHAKE_INTENSITY
local shake_speed_goal = goal * MAX_SHAKE_SPEED
colorCorrection.Brightness = brightness_goal
colorCorrection.Contrast = contrast_goal
colorCorrection.TintColor = Color3.fromRGB(255, color_goal, color_goal)
ShakeCamera:playShake(shake_intensity_goal)
end
local function actualizeMagnitude(distance: number)
if distance <= MIN_DISTANCE then
local goal = 1 - (distance / MIN_DISTANCE)
setEffects(goal)
end
end
heartbeatFunction = function(dt: number)
if not character.Parent then
heatbeatConnection:Disconnect()
return
end
local distance = (humanoidRootPart.Position - secretPart.Position).Magnitude
actualizeMagnitude(distance)
end
heatbeatConnection = RunService.Heartbeat:Connect(heartbeatFunction)
if not game:IsLoaded() then game.Loaded:Wait() end
--SERVICE
local RunService = game:GetService("RunService")
local ReplicatedStorage = game.ReplicatedStorage
local Lighting = game:GetService("Lighting")
--MODULES
local ShakeCamera = require(ReplicatedStorage.Camera.ShakeCamera)
--PLAYER
local player = game.Players.LocalPlayer
local character = player.Character
local humanoidRootPart = character.HumanoidRootPart:: BasePart
local humanoid = character.Humanoid:: Humanoid
--LIGHTING
local colorCorrection = Lighting.ColorCorrection
--WORKSCPACE
local Build = workspace:WaitForChild("Build")
local secretPart = Build:FindFirstChild("SecretPart")
--NOT CHANGE VALUE
local MIN_DISTANCE = 50
local MAX_DISTANCE = 15
local MAX_BRIGHTNESS = -0.8
local MAX_CONTRAST = 1
local MAX_SHAKE_SPEED = 2
local MAX_SHAKE_INTENSITY = 1.5
--CONNECTION
local heatbeatConnection
local heartbeatFunction
local function resetEffects()
colorCorrection.Brightness = 0
colorCorrection.Contrast = 0
colorCorrection.TintColor = Color3.fromRGB(255, 255, 255)
end
local function setEffects(goal: number, dt)
local brightness_goal = goal * MAX_BRIGHTNESS
local contrast_goal = goal * MAX_CONTRAST
local color_goal = 255 * (1 - goal)
local shake_intensity_goal = goal * MAX_SHAKE_INTENSITY
local shake_speed_goal = goal * MAX_SHAKE_SPEED
colorCorrection.Brightness = brightness_goal
colorCorrection.Contrast = contrast_goal
colorCorrection.TintColor = Color3.fromRGB(255, color_goal, color_goal)
ShakeCamera:playShake(shake_intensity_goal, dt)
end
local function actualizeMagnitude(distance: number, dt)
if distance <= MIN_DISTANCE then
local goal = 1 - (distance / MIN_DISTANCE)
setEffects(goal, dt)
end
end
heartbeatFunction = function(dt: number)
if not character.Parent then
heatbeatConnection:Disconnect()
return
end
local distance = (humanoidRootPart.Position - secretPart.Position).Magnitude
actualizeMagnitude(distance, dt)
end
heatbeatConnection = RunService.Heartbeat:Connect(heartbeatFunction)
local player = game.Players.LocalPlayer
local character = player.Character
local humanoid = character.Humanoid:: Humanoid
--libs
local VECTOR_3 = Vector3.new
local MATH_RANDOM = math.random
local ShakeCamera = {}
function ShakeCamera:playShake(shakeIntensity: number, dt :number): ()
local shakeOffset = Vector3.new(
MATH_RANDOM(-shakeIntensity, shakeIntensity),
MATH_RANDOM(-shakeIntensity, shakeIntensity),
MATH_RANDOM(-shakeIntensity, shakeIntensity)
)
local originalOffset = VECTOR_3(0, 0, 0)
humanoid.CameraOffset = originalOffset + shakeOffset
task.delay(dt, function()
humanoid.CameraOffset = originalOffset
end)
end
return ShakeCamera
its somewhat ineffective however its the easiest fix for the issue there
heartbeatFunction = function(dt: number)
if not character.Parent then
heatbeatConnection:Disconnect()
return
end
local distance = (humanoidRootPart.Position - secretPart.Position).Magnitude
actualizeMagnitude(distance)
end
heatbeatConnection = RunService.Heartbeat:Connect(heartbeatFunction)
The problem is that RunService.Heartbeat runs the function from a new thread every frame. Yeilds inside previously ran functions will not prevent new ones from running. A while loop should fix the issue:
while True do
local dt = RunService.Heartbeat:Wait() -- Here, :Wait() is used. :Wait() is quite different to :Connect(), it acts in a very similar way to task.wait(), but instead of waiting for some time, it waits for a signal (here, the next heartbeat signal)
if not character.Parent then
break
end
local distance = (humanoidRootPart.Position - secretPart.Position).Magnitude
actualizeMagnitude(distance)
end
local player = game.Players.LocalPlayer
local character = player.Character
local humanoid = character.Humanoid:: Humanoid
local canPlay = true
--libs
local VECTOR_3 = Vector3.new
local MATH_RANDOM = math.random
local ShakeCamera = {}
function ShakeCamera:playShake(shakeIntensity: number, shakeSpeed: number): ()
if not canPlay then return end
local shakeOffset = Vector3.new(
Vector3.xAxis * MATH_RANDOM(-shakeIntensity, shakeIntensity),
Vector3.yAxis * MATH_RANDOM(-shakeIntensity, shakeIntensity),
Vector3.zAxis * MATH_RANDOM(-shakeIntensity, shakeIntensity)
)
local originalOffset = Vector3.zero
humanoid.CameraOffset = originalOffset + shakeOffset
canPlay = false
task.wait(shakeSpeed)
canPlay = true
humanoid.CameraOffset = Vector3.zero
end
return ShakeCamera