Dont want to make the button yourself, download this model: Jump Button - Roblox
Introduction:
Hello! I’m kinglol(also known as Biack1st) today i’ll show you how to do super bomb survival styled buttons. Aka which are buttons that do something when you jump on them. This can be useful for puzzle games or really anything! For those of you who haven’t player Super Bomb Survival this is the effect:
As you can see, the spectate button will make you spectate when you jump on the button. This tutorial will teach you how to make something happen when you jump on a button
Modeling
Now, my model wont be a masterpiece for the sake of time. This part will tell you how to make the button model
First, make 2 parts, name the one you want for the button: ButtonPart and the base to be named: BasePart.
Making our hit detection
For this segment, we’ll set up our hit detection(no scripting yet, but soon).
First, insert a part, name it: ButtonDetect. After that make the size of the button detect part the same as the button. But make the Y value bigger. So your detect part should look like this:
My detect size is: 8, 12, 7.5
After you do that, make the transparency 1 and set cancollide to false.
Once you finish doing that, group the button by doing ctrl + G.
Scripting
Insert a script into the buttonpart
woo hoo! fun part. This part is complicated, but as long as you follow my directions, you’ll be alright
Variables
First, lets start off with our variables.
-- script inside button
local Button = script.Parent -- our button
local RunService = game:GetService("RunService")
local TrackedObjects = {} -- table for the characters that are in range.
local TrackedHumanoid = {}
local DetectPart = Button.Parent.ButtonDetect -- detect part
Once we do that, lets set up our detection. Our detection will use region 3. Just follow along and you’ll be all good.
local DetectDimensions = Region3.new(DetectPart.Position - DetectPart.Size / 2, DetectPart.Position + DetectPart.Size / 2) -- gets the dimensions for our detect
local Blacklist = OverlapParams.new() -- this will be our blacklist. We need a blacklist so that our button wont be detected by our detection
Blacklist.FilterType = Enum.RaycastFilterType.Blacklist -- sets the filter type to blacklist
Blacklist.FilterDescendantsInstances = {Button.Parent} -- blacklists the button model and it's decendants
Next, lets script our action. This will be done via a function. So just make the function’s content do what you want. For me, I want it to change the button’s color.
local function Action()
print('jumped on')
Button.BrickColor = BrickColor.Random()
end
The next thing we need to do, is make the detection actually do something with what it detects. So let’s start. Make sure too looks at my comments so you can understand what each part of the script is doing.
local function Track()
local DetectHitbox = workspace:GetPartBoundsInBox(DetectDimensions.CFrame, DetectDimensions.Size, Blacklist) -- gets the part's in our detection region.
for i,Object in pairs(DetectHitbox) do -- loops through everything inside of the region
local Character = Object:FindFirstAncestorWhichIsA("Model") -- checks if the object has a model Ancestor
if Character and table.find(workspace:GetPartBoundsInBox(DetectDimensions.CFrame, DetectDimensions.Size, Blacklist), Object) then -- checks if the character exists and checks if the object is still inside our detection, as the object could've left by then.
local Humanoid = Character:FindFirstChildWhichIsA("Humanoid") -- gets the humanoid object of a character
if Humanoid then -- checks if the humanoid exists
local Player = game.Players:GetPlayerFromCharacter(Character) -- get the player object from the character. This is to check if the character model we got was an actual player and not a npc.
if Player and not table.find(TrackedObjects, Character) then -- checks if the player is there, also checks if the character is NOT apart of trackedobjects table.
table.insert(TrackedObjects, Character) -- adds the character to the tracked objects table.
end
end
end
end
for i,v in pairs(TrackedObjects) do -- once we add everything inside the tracked objects, we'll start checking when the humanoid jumps.
local Humanoid = v:FindFirstChildWhichIsA("Humanoid") -- checks if the character has a humanoid
if Humanoid and not table.find(TrackedHumanoid, Humanoid) then -- checks if the humanoid is NOT a part of the tracked humanoid table
table.insert(TrackedHumanoid, Humanoid) -- adds the humanoid to the table
Humanoid.StateChanged:Connect(function(OldState, NewState) -- this will fire everytime a humanoid's state changes.
if OldState == Enum.HumanoidStateType.Freefall or OldState == Enum.HumanoidStateType.Jumping then -- checks if the humanoid was just in the free fall state or was just in the jumping state.
if table.find(TrackedObjects, v) then -- checks if the tracked object is still in the tracked objects folder. As it could've been removed by this time.
Action() -- fires our action function
coroutine.yield() -- this is IMPORTANT, this is so that our statechanged function wont fire again.
end
end
end)
end
end
end
After that, our button should work. BUT there’s 2 issues, first, we never called our Track function, we’ll do that later. AND it’ll still fire after the character left the detection. Which is a huge issue. We’ll start off by creating a untrack function. To stop tracking objects that are outside of the detection
Make sure to read my comments if you dont understand something.
local IsThere = false -- this will be the value to check if the character is still there.
local function Untrack()
local NotThereChar -- this is currently nil, but later, we'll set this to a character model
local DetectHitbox = workspace:GetPartBoundsInBox(DetectDimensions.CFrame, DetectDimensions.Size, Blacklist) -- creates the detect hitbox again
if DetectHitbox[1] == nil then -- checks if the detect hitbox is empty
for i,v in pairs(TrackedObjects) do -- loops through everthing
table.remove(TrackedObjects, i) -- removes the object
end
for i,v in pairs(TrackedHumanoid) do -- loops through every humanoid we tracked
table.remove(TrackedHumanoid, i) -- removes the humanoid from the table.
end
end
for i, Object in pairs(DetectHitbox) do -- loops through everything that was detected in our hitbox
for i,Character in pairs(TrackedObjects) do -- goes through our tracked objects
for i,v in pairs(Character:GetDescendants()) do -- loops through all the items of the character.
if v == Object then -- checks if the character's part is the object in the hitbox.
IsThere = true -- sets isthere to true
break -- breaks all loops so that the isthere wont be set to false again. As some objects of the character may be inside the hitbox, while others not
else
NotThereChar = Character -- sets notThereChar to the character.
IsThere = false -- sets isthere to false
end
end
end
end
if IsThere == false then -- checks if is there is false
table.remove(TrackedObjects, table.find(TrackedObjects, NotThereChar)) -- removes the character from the tracked objects table
if NotThereChar ~= nil and NotThereChar:IsA("Model") then -- checks if the nottherechar is nil and if it's a model
table.remove(TrackedHumanoid, table.find(TrackedHumanoid, NotThereChar:FindFirstChildWhichIsA("Humanoid"))) -- removes the character's humanoid from the tracked humanoids.
end
end
end
--- connections, this is where we connect our track and untrack functions
RunService.Heartbeat:Connect(Untrack)
RunService.Heartbeat:Connect(Track)
and that’s all!
Final Code
-- script inside button
local Button = script.Parent -- our button
local RunService = game:GetService("RunService")
local TrackedObjects = {} -- table for the characters that are in range.
local TrackedHumanoid = {}
local DetectPart = Button.Parent.ButtonDetect -- detect part
local DetectDimensions = Region3.new(DetectPart.Position - DetectPart.Size / 2, DetectPart.Position + DetectPart.Size / 2) -- gets the dimensions for our detect
local Blacklist = OverlapParams.new() -- this will be our blacklist. We need a blacklist so that our button wont be detected by our detection
Blacklist.FilterType = Enum.RaycastFilterType.Blacklist -- sets the filter type to blacklist
Blacklist.FilterDescendantsInstances = {Button.Parent} -- blacklists the button model and it's decendants
local function Action()
print('jumped on')
Button.BrickColor = BrickColor.Random()
end
local function Track()
local DetectHitbox = workspace:GetPartBoundsInBox(DetectDimensions.CFrame, DetectDimensions.Size, Blacklist) -- gets the part's in our detection region.
for i,Object in pairs(DetectHitbox) do -- loops through everything inside of the region
local Character = Object:FindFirstAncestorWhichIsA("Model") -- checks if the object has a model Ancestor
if Character and table.find(workspace:GetPartBoundsInBox(DetectDimensions.CFrame, DetectDimensions.Size, Blacklist), Object) then -- checks if the character exists and checks if the object is still inside our detection, as the object could've left by then.
local Humanoid = Character:FindFirstChildWhichIsA("Humanoid") -- gets the humanoid object of a character
if Humanoid then -- checks if the humanoid exists
local Player = game.Players:GetPlayerFromCharacter(Character) -- get the player object from the character. This is to check if the character model we got was an actual player and not a npc.
if Player and not table.find(TrackedObjects, Character) then -- checks if the player is there, also checks if the character is NOT apart of trackedobjects table.
table.insert(TrackedObjects, Character) -- adds the character to the tracked objects table.
end
end
end
end
for i,v in pairs(TrackedObjects) do -- once we add everything inside the tracked objects, we'll start checking when the humanoid jumps.
local Humanoid = v:FindFirstChildWhichIsA("Humanoid") -- checks if the character has a humanoid
if Humanoid and not table.find(TrackedHumanoid, Humanoid) then -- checks if the humanoid is NOT a part of the tracked humanoid table
table.insert(TrackedHumanoid, Humanoid) -- adds the humanoid to the table
Humanoid.StateChanged:Connect(function(OldState, NewState) -- this will fire everytime a humanoid's state changes.
if OldState == Enum.HumanoidStateType.Freefall or OldState == Enum.HumanoidStateType.Jumping then -- checks if the humanoid was just in the free fall state or was just in the jumping state.
if table.find(TrackedObjects, v) then -- checks if the tracked object is still in the tracked objects folder. As it could've been removed by this time.
Action() -- fires our action function
coroutine.yield() -- this is IMPORTANT, this is so that our statechanged function wont fire again.
end
end
end)
end
end
end
local IsThere = false -- this will be the value to check if the character is still there.
local function Untrack()
local NotThereChar -- this is currently nil, but later, we'll set this to a character model
local DetectHitbox = workspace:GetPartBoundsInBox(DetectDimensions.CFrame, DetectDimensions.Size, Blacklist) -- creates the detect hitbox again
if DetectHitbox[1] == nil then -- checks if the detect hitbox is empty
for i,v in pairs(TrackedObjects) do -- loops through everthing
table.remove(TrackedObjects, i) -- removes the object
end
for i,v in pairs(TrackedHumanoid) do -- loops through every humanoid we tracked
table.remove(TrackedHumanoid, i) -- removes the humanoid from the table.
end
end
for i, Object in pairs(DetectHitbox) do -- loops through everything that was detected in our hitbox
for i,Character in pairs(TrackedObjects) do -- goes through our tracked objects
for i,v in pairs(Character:GetDescendants()) do -- loops through all the items of the character.
if v == Object then -- checks if the character's part is the object in the hitbox.
IsThere = true -- sets isthere to true
break -- breaks all loops so that the isthere wont be set to false again. As some objects of the character may be inside the hitbox, while others not
else
NotThereChar = Character -- sets notThereChar to the character.
IsThere = false -- sets isthere to false
end
end
end
end
if IsThere == false then -- checks if is there is false
table.remove(TrackedObjects, table.find(TrackedObjects, NotThereChar)) -- removes the character from the tracked objects table
if NotThereChar ~= nil and NotThereChar:IsA("Model") then -- checks if the nottherechar is nil and if it's a model
table.remove(TrackedHumanoid, table.find(TrackedHumanoid, NotThereChar:FindFirstChildWhichIsA("Humanoid"))) -- removes the character's humanoid from the tracked humanoids.
end
end
end
--- connections, this is where we connect our track and untrack functions
RunService.Heartbeat:Connect(Untrack)
RunService.Heartbeat:Connect(Track)
FINAL RESULT
Polls
As this is my first tutorial, i’d like some feedback via polls. Make sure to answer these!
From 1-10 how useful was this to you?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
0 voters
Did you learn anything new?
- Yes
- No
0 voters
How likely are you to use this?
- I’ll surely use this.
- I might use it.
- No, not really.
0 voters
Outro
I really hope that this could help you in any way! This style of buttons are pretty unique in my opinion, as not many games do this. These types of buttons are especially good for puzzle games. Or if you want to make your game have a unique style of buttons! If you have any questions, feedback, feel like I missed something or anything i could’ve done better then feel free to say it below!