RenderStepped loop interferes with debounce

I’m using a RenderStepped loop to make a Billboard Gui change its visibility depending on how far the player is from a part. I’ve made a “Press E to interact” function that will change the text of the Billboard Gui and also print the word “activated”. I only want “activated” to be printed once when “E” is pressed but it prints multiple times. I’ve tried adding a debounce variable but the RenderStepped loop interfered with it.


function Interaction()
inputService.InputBegan:Connect(function(input, gameProcessed)
	if input.KeyCode == Enum.KeyCode.E and gameProcessed == false then --If "E" Pressed
	frame.Text = "M A G I C" -- Changes BillBoardGui Text
	print("activated")
	wait(2)
	frame.Text = "PRESS E FOR MAGIC" --Changes Text back to original
	end
	end)
end

runService.RenderStepped:Connect(function() --RenderStepped Loop
	
	if math.floor((interactive.Position - plr.Character.HumanoidRootPart.Position).Magnitude) <= 10 then --Activates when player is close to part
	
	frame.Visible = true --Make BillBoardGui Visible
	
	Interaction() --Start Interaction Function
	
	else
		frame.Visible = false --Turn invisible if more than 10 studs from part
	
	end
end)

It’s not that RenderStepped is interfering with the debounce here, it’s that every frame before rendering tasks begin, you’re calling a function that connects to InputBegan. You actually have a deeper problem here in that you’re creating new events every frame so you now have many independently hooked functions with their own debounces or whatever. That needs to change.

First and foremost: stop using RenderStepped, because you don’t have any tasks here that should reasonably be executed before a frame renders. Use Heartbeat instead.

You will want to separate your tasks here. You will ultimately have two: the UserInputService event and then the RunService event connection. For InputBegan, what you should be doing is only completing the action if a condition is met. The RunService event will set this flag.

Here’s a code sample incorporating the above feedback that better shows how to achieve this:

local inRange = false

inputService.InputBegan:Connect(input, gameProcessedEvent)
    if gameProcessedEvent then return end

    if input.KeyCode == Enum.KeyCode.E and inRange then
        frame.Text = "M A G I C"
        print("activated")
        wait(2)
        frame.Text = "PRESS E FOR MAGIC"
    end
end)

runService.Heartbeat:Connect(function ()
    inRange = (interactive.Position - plr.Character.HumanoidRootPart.Position).Magnitude <= 10
    frame.Visible = inRange
end)
2 Likes