Ah yes, we want to make a player's character's walkspeed increase upon touching a physical object in the game! Great!
To start you should keep in mind your goal and outline what you will need to achieve it.
Awesome. Now, we already have our character, a part in workspace, and the server script. But we need to tweak the code in the server script just a bit to get it where we need to be.
Let's start with learning what a debounce is and why we should use them!
Now let's learn a little bit about Loops!
Great!
Now, here was your original code:
function onTouch(hit)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
humanoid.Walkspeed +1
wait(1)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
humanoid.Walkspeed +1
repeat
end
Alright, so we've touched on the issues with the original code.
Let's make a correct version of this script and talk about why it's better!
Corrected Script:
local Part = workspace:WaitForChild("Part")
local dbTable = {}
local MaxSpeed = 25
local function CheckTable(name)
for index, playerName in pairs(dbTable) do
if playerName == name then
return true
end
end
return false
end
local function RemoveFromTable(name)
for index, playerName in pairs(dbTable) do
if playerName == name then
table.remove(dbTable, index)
end
end
end
local function onTouch(hit)
if hit.Parent:FindFirstChild("Humanoid") and CheckTable(hit.Parent.Name) == false then
local humanoid = hit.Parent:FindFirstChild("Humanoid")
local playerName = hit.Parent.Name
table.insert(dbTable, playerName)
while true do
if humanoid.WalkSpeed == MaxSpeed then
break
end
humanoid.WalkSpeed = humanoid.WalkSpeed + 1
wait(1)
end
RemoveFromTable(playerName)
end
end
Part.Touched:Connect(onTouch)
Alright now, that all seems very complicated.
But let's break it down line by line so we can develop a full understanding of what's going on and hopefully open our mind up to new techniques and ways of thinking!
local Part = workspace:WaitForChild("Part")
This establishes a variable called "Part" and sets it equal to an object in the workspace named "Part". Whatever object the players will be touching to increase their walkspeed. The :WaitForChild() part just allows the code to wait until the part is actually loaded into the game. That way if the script loads faster than the part, we won't throw an error!
local dbTable = {}
Instead of using a boolean as our standard debounce, we need this script to be functional and available to all players, regardless if another player already touched it. We wouldn't want one player to touch the part and then have another player have to wait until the loop is done for that first player before they can touch it, right? Right. So instead we've created a blank table called "dbTable". This will be used to store player's names who have touched the part and currently are having their walkspeeds increased. Once we're done increasing their walkspeeds, we'll remove their name from the table so the cycle can repeat!
local function CheckTable(name)
for index, playerName in pairs(dbTable) do
if playerName == name then
return true
end
end
return false
end
What does our CheckTable(name) function do? This function utilizes a simple for loop and conditional statement to iterate through our dbTable and check to see if any of the names inside the table match the argument we gave to the function (name). If the name we passed as an argument matches one of the names inside the table, the function will stop iterating through the table and return itself as the boolean value of true. If it doesn't find a match, it will iterate through the rest of the table, the loop will end, and the code will reach return false.
local function RemoveFromTable(name)
for index, playerName in pairs(dbTable) do
if playerName == name then
table.remove(dbTable, index)
end
end
end
What does our RemoveFromTable(name) function do? This function, again, utilizes the very same for loop and conditional statement that we used in the CheckTable(name) function. Only this time, instead of returning true if the names matched, we're going to remove the player's name from the table by using table.remove(dbTable, index)
The purpose of using these two functions is so that, when a player touches the part, we'll check the table to see if their name is already in the table. If it isn't, we'll continue through the rest of the onTouch(hit) function and also add their name to the table (Since they've now touched the part). Once the code is done adding their name and increasing the player's WalkSpeed, it will then remove their name from the table so that they will be able to touch the part again.
local function onTouch(hit)
if hit.Parent:FindFirstChild("Humanoid") and CheckTable(hit.Parent.Name) == false then
local humanoid = hit.Parent:FindFirstChild("Humanoid")
local playerName = hit.Parent.Name
table.insert(dbTable, playerName)
while true do
if humanoid.WalkSpeed == MaxSpeed then
break
end
humanoid.WalkSpeed = humanoid.WalkSpeed + 1
wait(1)
end
RemoveFromTable(playerName)
end
end
Part.Touched:Connect(onTouch)
Alright, here it is. The main function of the script. What's going on with this one?
So initially we start off with a conditional statement that needs TWO things to be a certain away in order to continue. We need the Parent of hit to contain an object named "Humanoid", AND we need our CheckTable(hit.Parent.Name) to return false!
If both of these conditions are met, we move on!
These next two lines are just establishing two variables. We establish our humanoid variable and our playerName variable. I consider these to be self-explanatory but if you have questions, just ask in the comments.
Next, we are going to use table.insert(dbTable, playerName) to insert the player's name into the table.
Next is a While True Do loop. This is a loop you should have read about in the Loops article mentioned earlier. It will continue looping until the statement between While and **Do ** is no longer true.
We have currently made that statement humanoid.WalkSpeed < MaxSpeed. Once we've increased WalkSpeed all the way up to our MaxSpeed that we established earlier, the loop will stop. We will then fire off our RemoveFromTable(playerName) function.
The final line is simply our connection line. This connects the onTouch(hit) function to the part's **Touched ** event.
I truly hope this short tutorial has helped you think in a new creative way and enables you to grow and learn as a programmer here on Roblox! Let me know if you have any questions!
**This all took me a good 30-45 minutes to draft up and double check. So if it helped you, I would greatly appreciate an up-vote and acceptance of it as an answer. Thanks! **