basically i started scripting yesterday, and today tried writing a simple speed script from scratch, that would make it so if you connected with a part, it would give you plus 1 speed every second. it's not working though. Help would be great
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
First of all, Walkspeed is not a property of Humanoid. It should be "WalkSpeed", the capitalization is important. Secondly, it seems you are trying to do a loop there with repeat. You may want to check out different types of loops such as while loops, for loops and repeat loops. You may go to here for more information on types of loops.
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.
Goal: Increase character's walkspeed upon touching a part.
What will I need?
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! - Debounce
Now let's learn a little bit about Loops! - Loops
Great!
Now, here was your original code:
function onTouch(hit) local humanoid = hit.Parent:FindFirstChild("Humanoid") -- Established humanoid variable? Check. humanoid.Walkspeed +1 -- Uh oh, we have an addition operator instead of an equal sign? -- And WalkSpeed is not capitalized correctly! wait(1) -- Tells the script to wait for one second. local humanoid = hit.Parent:FindFirstChild("Humanoid") -- For some reason we re-established our humanoid variable. -- Uh oh, this violates our DRY principle (Don't Repeat Yourself)! humanoid.Walkspeed +1 -- Again, DRY! repeat -- Improperly began a repeat loop but didn't put any code inside its scope or end properly 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") -- Change this to your part's name local dbTable = {} local MaxSpeed = 25 -- We've created this variable to be our max WalkSpeed allowed. 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) -- connection line for the part to the function
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 ourdbTable
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) -- connection line for the part to the function
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! **
Do this -
Function onTouch(hit) local humanoid = hit.Parent:FindFirstChild("Humanoid") while wait(1) do humanoid.WalkSpeed = humanoid.WalkSpeed + 1 end
fill here with your info Example: game.workspace.part.Touched(onTouch) fill here with your info
Should work.