How to work around the RunService

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
1 Like

could you show me the playShake code?

1 Like

yea !

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

i think a simple fix to this would be to replace the wait with

task.delay(2, function() -- replace 2 with however long the delay needs to be
  humanoid.CameraOffset = originalOffset
end)

hope this helps

no because a runservice play function any deltatime

1 Like

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.

task.delay(DeltaTime, function()
 humanoid.CameraOffset = originalOffset
end)
1 Like

its not work for me

my code:

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)
1 Like

this should work;

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

1 Like

its not working the probleme is runservice

1 Like

Do you mean it runs too often, and it should only run every like 2 second if you have a wait time of 2 seconds, or something else?

2 Likes

it’s exactlyy itt !!!

1 Like
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
1 Like

i found a problem

function ShakeCamera:playShake(shakeIntensity: number): ()
   if not canPlay then return end
   
   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
   
   canPlay = false
   
   task.wait(2)
   
   canPlay = true
   
   humanoid.CameraOffset = VECTOR_3(0, 0, 0)
end
1 Like

What is it …?


1 Like

please use Vector3.zero over Vector3.new(0,0,0), you’d also benefit using Vector3.xAxis, Vector3.yAxis, Vector3.zAxis multiplied by these values:

:slight_smile:

2 Likes
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


2 Likes
local shakeOffset = 
    Vector3.xAxis * math.random(-shakeIntensity, shakeIntensity) +
    Vector3.yAxis * math.random(-shakeIntensity, shakeIntensity) +
    Vector3.zAxis * math.random(-shakeIntensity, shakeIntensity)
1 Like

its not work for me…

sorryy…

1 Like