How to make a button

I am attempting to make a button that when the player stands on it, it goes down and it goes back up when the player isn’t standing on it. I made the button by putting a ghost part above the button that acts as a hitbox, the only problem is it doesn’t always work. Sometimes I’ll jump onto the button, and it works fine, other times it doesn’t even detect me jumping on or off. Is there any other way I could detect the player more efficiently? This is difficult because I am using the button in different places, for different things, so I have to leave room for all the different things I may use the button for.

1 Like

2 things we need, screen shot of the button in the explorer (the whole setup) and the script you used. That will help me let you know where you went wrong and how I can help.

Hello There!

You should use the Built in .Touched Function to know when the player touches it. To detect when they stop touching use the other Built in .TouchEnded Function to know when they stop touching.

If this was helpfull please tell me i would be happy to know and to help again another time! :smiley:

Kind Regards, The_IntoDev.

“Set up”:
ButtonImage
ButtonActivationBox attributes:
actiavationBoxAtt

I just have a regular part as my button, which in image 1 is named “Button1”, and I have the ghost part I mentioned named “ButtonActivateBox”. The ghost part has some attributes that I use in my code:

buttonId: Lets me know what kind of button it is
cubeId: Lets me know which button it belongs too
down: Lets me know if it is down
id: What kind of activation it is, for example is a person you talk to or a button you stand on

As for the script, I have a lot in the script, it would almost be impossible to share the script without sharing over 1,000 lines of code, but I can give you an example.

Client:

function _rootPartTouched() -- This is called almost immediately after the script starts(Works)
   _localCharacter.PrimaryPart.Touched:Connect(function(hit)
      -- I have some code here that checks to make sure that the part the player touches is the button's hitbox, then lets the server know by firing a remote event
   end)
   _localCharacter.PrimaryPart.TouchEnded:Connect(function(hit)
      -- I have some more code here that fires the server again when the player stops touching the hitbox 
   end)
end

Server:

function _remoteEventCalled(player, id, data1, data2, data3, data4, data5) -- Because I only use 1 remote event this function handles a lot
   -- I have some 'if statements' that check if the function was fired because the player touched a button's hitbox
   if (data5 and activationItem:GetAttribute("down") == false) then -- Data5 is a boolean sent by the client to determine if the player is standing on the button
      -- Tween the buttons down(Works)
      _tween1 = _tweenService:Create(part, buttonTweenInfo, {Position = Vector3.new(part.Position.X, _startingPos[1] - 3, part.Position.Z)})
      _tween2 = _tweenService:Create(activationItem, buttonTweenInfo, {Position = Vector3.new(activationItem.Position.X, _startingPos[2] - 3, activationItem.Position.Z)})			
      _tween1:Play()
      _tween2:Play()

      activationItem:SetAttribute("down", true)
      -- I have some code here that does those "things" I mentioned
   elseif (data5 == false) then
      if (_tween1) then -- if the button is going down, stop it. I have another for tween2, but I trying to keep this short
	     _tween1:Cancel()
         _tween1 = nil
      end
	  -- Tween the buttons up(Works)		
	  _tween1 = _tweenService:Create(part, buttonTweenInfo, {Position = Vector3.new(part.Position.X, _startingPos[1], part.Position.Z)})
	  _tween2 = _tweenService:Create(activationItem, buttonTweenInfo, {Position = Vector3.new(activationItem.Position.X, _startingPos[2], activationItem.Position.Z)})
				
	  _tween1:Play()
	  _tween2:Play()
      
      activationItem:SetAttribute("down", false)
   end
end

The problem seems to be the client script, I have put some prints and the times I stand on the button, and it doesn’t go down, the .Touched event doesn’t fire, thus, the server doesn’t fire. So, I’m just trying to figure out why it doesn’t always detect the player.

I am using .Touched and .TouchedEnded, I believe they might even be the problem because they don’t always fire when the player touches a part.

Hello again!

Sorry for the slow response I was doing something else, but I see the issue now. You are only detecting when the players Root is touched, which is only a certain part of the character, that is why it is only firing sometimes. You should loop through the player and for each BasePart you will detect their touch.

Hopefully this was helpfull, tell me if you are having any more problems!

1 Like

I have tried this, and it leads to issues, like if I jump onto the button, my hand might trigger the button, but then my hand leaves as I fall, and the button doesn’t move because it thinks I’m not touching it.

Are you using a Variable to keep track of if they are touching or not?

If you are not, it might cause issues.

Again, sorry for slow replies i am doing something.

That is what this is:

activationItem:SetAttribute("down", true)

You could try using WorldRoot:GetPartBoundsInBox() as a more reliable way to check if something is in the hitbox, as the Touched event tends to be finnicky from my and your experience.

1 Like

If you are doing a jump, you could listen for the jump.

humanoid.Jumping:Connect(function(isActive)
	print("Jumping: ", isActive)
end)

That was definitely another solution, Touched and TouchEnded is actually not made for what he is using it for now that i am thinking about it.

I have found a solution! I made a Script that works, all you have to do is replace the print statements in the OnPress and OnUnpress with the code you want, so i guess tweening and other stuff.

Here is an Image of the button layout:
image

Here is the Code i used:

local Button = script.Parent.Button
local Hitbox = script.Parent.Hitbox

local function OnPress()
	print("Button Was Pressed")
end

local function OnUnpress()
	print("Button Got Unpressed")
end

local Touch = {}

Hitbox.Touched:Connect(function(hit)
	if game.Players:FindFirstChild(hit.Parent.Name) then
		if #Touch == 0 then
			OnPress()
		end
		
		table.insert(Touch, hit.Name .. "-" .. hit.Parent.Name)
	end
end)

Hitbox.TouchEnded:Connect(function(hit)
	if game.Players:FindFirstChild(hit.Parent.Name) then
		task.wait(0.1)
		
		table.remove(Touch, table.find(Touch, hit.Name .. "-" .. hit.Parent.Name))
		
		if #Touch == 0 then
			OnUnpress()
		end
	end
end)

Hopefully this was helpfull, i hope you see it!