Help on debouncing Runservice.Heartbeat:connect(function()

So yesterday I made to post on help in this door I was making, two times I was helped and it worked perfectly. Now I think I’m in the last stretch of completing this thing,

How the door works:
So when a player enters a 10-stud radius within the door it’ll open 180 degrees, and when the leave it the door closes, it works fine except for the part that when you get in the 10-stud radius it goes absolutely berserk:
-note roblox won’t frigging let me upload it here so I uploaded it to yt:
Door goes absolutely berserk when you get in the 10-stud radius [ROBLOX] - YouTube
I know how to debounce but I don’t know how you would debounce a runservice, does it work the same, how would it work, what would it look like?
script, server script under the door model:

local RP = script.Parent.PrimaryPart
local Radius = 10
local DetectionPart = script.Parent.Detectionpart
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(plr)
	game:GetService("RunService").Heartbeat:Connect(function()--this is were the runservice thing is, 
		local Character = plr.Character or plr.CharacterAdded:Wait()
		local door = {}
		local HRP = Character.HumanoidRootPart
		if (HRP.Position - DetectionPart.Position).Magnitude <= Radius then
			local DoorTween = TweenService:Create(RP, TweenInfo.new(0.25,Enum.EasingStyle.Sine), {CFrame = RP.CFrame * CFrame.Angles(0,math.rad(-180),0)})
			DoorTween:Play()
			wait(0.2)
			door.Open = true
		elseif (HRP.Position - DetectionPart.Position).Magnitude > Radius and door.Open then
			local EndDoorTween = TweenService:Create(RP, TweenInfo.new(0.5,Enum.EasingStyle.Sine), {CFrame = RP.CFrame * CFrame.Angles(0,math.rad(180),0)})
			EndDoorTween:Play()
			wait(0.2)
			door.Open = false
		end
	end)
end)

So the problem is: it keeps running the code over and over again when we are in the 10-stud radius, so the tween is continually going a 180 degrees turn. Any way to debounce it, like I said before I have no idea how you would be able to, so you talented people here on the dev fourm probably do, or know whats wrong.

2 Likes

I don’t think you can debounce a hearbeat, renderstepped, or stepped, without using another function (correct me if im wrong btw). Heartbeat, stepped, and render stepped to my knowledge, constantly fires, and there’s really no way of debounce the loop.

An alternative is to have a loop in a loop such as a while - do loop, but it is highly not recommended.

You’re probably better off running a while - do or repeat - until loop instead.

1 Like

Do you think I can make a while loop in the runservice, and in the while loop I’ll have it where I debounce it? Do you think that’ll work?

RunService.Heartbeat has one argument known as delta time, which is the delay between frames
We can use an elapsed variable to record the time between and use that as a “debounce”

local elapsed = 0
game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
   elapsed += deltaTime
   if elapsed > .2 then
      -- do stuff
      elapsed = 0
   end
end)

Edit forgot to reset the elapsed :stuck_out_tongue:

5 Likes

Wow, that seems pretty cool, so this:

if elapsed > .2 then

so the .2 is practically the delay time

That’s correct, you can use that method for delay time.
It’s actually very useful in other engines too that have an update method and don’t necessarily have wait() or a easy to use sleep function :stuck_out_tongue:

1 Like

Just make sure to set elapsed to 0 afterwards otherwise it’ll start running every frame past the first 0.2 seconds.

3 Likes

A side question, would using a while - do loop with a wait() the same as using delta time delay? Which way is more optimized?

1 Like

the slowest time wait() can be is .03 (dt is needed for times under that)
delta time from my understanding can be more accurate than wait too

2 Likes