Repeatable Button

Hello, good day, everyone. I’m wondering how do i make a button repeatable, for example, when a player touches a button, it opens up a path, then 10 seconds after, it disappears then it will be pushable again. I have searched on how to do this but i came up short. I’m also planning to make this open-source so it will really help if you helped me how to do it. Here’s the code:

-- Core
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Variables
local ButtonHandler = require(ReplicatedStorage:WaitForChild("Modules"):WaitForChild("Functionality"):WaitForChild("ButtonHandler"))

-- Functions
ButtonHandler:Init()
-- ButtonActions

-- Button Tween
local TweenService = game:GetService("TweenService")
local ButtonStages = {
	DefaultColor = Color3.fromRGB(138, 255, 146),
	PressedColor = Color3.fromRGB(0, 0, 0)
}

local ButtonTweenInfo = TweenInfo.new(
	.5,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.Out,
	0,
	false,
	0
)

-- Variables
local ButtonActions = {}
local ButtonsFolder = workspace:WaitForChild("Game"):WaitForChild("Buttons")

-- Function
local function GetButtonByID(id)
	for _, child in ipairs(ButtonsFolder:GetChildren()) do
		child:WaitForChild("ID")
		if child.ID.Value == id then
			return child
		end
	end
end

function ButtonActions:Run(id)
	local button = GetButtonByID(id)
	if button then
		button:WaitForChild("Button")
		local ButtonTween = TweenService:Create(button.Button, ButtonTweenInfo, {Position = button.Button.Position + Vector3.new(0, -.3, 0), Color = ButtonStages.PressedColor})
		ButtonTween:Play()
		require(script:WaitForChild(tostring(id))):Execute()
	end
end

-- Return
return ButtonActions
-- Child of ButtonActions

-- Services
local TweenService = game:GetService("TweenService")

 -- Variables
local Obstacle = game.Workspace.Game.Obstacles.ObstaclePartA

local ObstacleTweenInfo = TweenInfo.new(
	0,
	Enum.EasingStyle.Quint,
	Enum.EasingDirection.Out,
	0,
	false,
	0
)

local Functions = {}

-- Execute
function Functions:Execute()
	print("Button with the ID" .. script.Parent.Name .."was pressed")
	
	local ObstacleTween = TweenService:Create(Obstacle, ObstacleTweenInfo, {Transparency = 1, Position = Vector3.new(0, -25, 0)})
	ObstacleTween:Play()
	-- wait(2)
	-- local ObstacleTween = TweenService:Create(Obstacle, ObstacleTweenInfo, {Transparency = 0, Position = Vector3.new(0,-25,0)}) 
	-- ObstacleTween:Play()  - This just returns the obstacle back to it's original position, and that's only progress i've made
end

-- Return
return Functions
-- ButtonHandler

local ButtonActions = require(script.Parent.ButtonActions)

local Buttons = {}
local ButtonHandler = {}

local buttonsFolder: Folder = workspace:WaitForChild("Game"):WaitForChild("Buttons")

local function FindButton(id)
	for _, child in ipairs(buttonsFolder:GetChildren()) do
		if child.Name == "ButtonModel" then
			child:WaitForChild("ID")
			if child.ID.Value == id then
				return child
			end
		end
	end	
end

function ButtonHandler:Init()
	for _, child in ipairs(buttonsFolder:GetChildren()) do
		if child.Name == "ButtonModel" then
			child:WaitForChild("ID")
			Buttons[child.ID.Value] = false
		end
	end
end

local OnChildAdded = function (child)
	child:WaitForChild("Button")
	child:WaitForChild("ID")
	child.Button.Touched:Connect(function ()
		if Buttons[child.ID.Value] == true then return end
		Buttons[child.ID.Value] = true
		ButtonActions:Run(child.ID.Value)
	end)
end

buttonsFolder.ChildAdded:Connect(OnChildAdded)
for _, child in ipairs(buttonsFolder:GetChildren()) do
	OnChildAdded(child)
end

return ButtonHandler

This isn’t the original code, the original code is from [OS GAME] Push The Button. This version only affects a client, whilst the original affects the server (of course with some little tweaks, with a little help from the DevForum community).

You can make something similar to this :

local running = false -- You can change it to debounce
local function buttonactions()
   -- When the part gets touched, this code will run
end

game.Workspace.Part.Touched:Connect(function(hit)
    if running == false then
       running = true
       print("Part Touched!")
       buttonactions()
      -- You can copy the part in the workspace and then put it in the Lighting so when the part gets destroyed you can clone it back to the workspace and then press it again.
       part:Destroy()
       wait(10)
       game.Lighting.Part:Clone().Parent = workspace
       running = false
    end
end)

I tried it but it just keeps repeating “Part Touched!”

I personally don’t like .Touched. It’s unstable and it doesn’t work properly.
I think you should use a ClickDetector for this.
Or if you still want to fire this when a player touches the button, you can use .Magnitude.

1 Like