I have this 2-way teleporter script that teleports the player to the other pad, which is also the way back. I was wondering if I could make 1 function and run it when either pad is touched rather than having 2 different ones.
local parent = script.Parent
local pad1 = parent:WaitForChild("Pad1")
local pad2 = parent:WaitForChild("Pad2")
local pad1Enabled = pad1:WaitForChild("Enabled")
local pad2Enabled = pad2:WaitForChild("Enabled")
pad1.Touched:Connect(function(part)
if not pad1Enabled.Value and not pad2Enabled.Value then
if part.Parent:FindFirstChild("Humanoid") then
part.Parent:SetPrimaryPartCFrame(pad2.CFrame + Vector3.new(0, 2, 0))
end
pad1Enabled.Value = true
pad2Enabled.Value = true
wait(2)
pad1Enabled.Value = false
pad2Enabled.Value = false
end
end)
pad2.Touched:Connect(function(part)
if not pad1Enabled.Value and not pad2Enabled.Value then
if part.Parent:FindFirstChild("Humanoid") then
part.Parent:SetPrimaryPartCFrame(pad1.CFrame + Vector3.new(0, 2, 0))
end
pad1Enabled.Value = true
pad2Enabled.Value = true
wait(2)
pad1Enabled.Value = false
pad2Enabled.Value = false
end
end)
This is one of those instances where you have a couple variables you can factor out. Here is what I could reduce it to (untested):
local parent = script.Parent
local pad1 = parent:WaitForChild("Pad1")
local pad2 = parent:WaitForChild("Pad2")
local function touchTeleportTo(source, destination)
return function(part)
if source.Enabled.Value or destination.Enabled.Value or not part.Parent:FindFirstChild('Humanoid') then
return
end
part.Parent:SetPrimaryPartCFrame(destination.CFrame + Vector3.new(0, 2, 0))
source.Enabled.Value = true
destination.Enabled.Value = true
wait(2)
source.Enabled.Value = false
destination.Enabled.Value = false
end
end
pad1.Touched:Connect(touchTeleportTo(pad1, pad2))
pad2.Touched:Connect(touchTeleportTo(pad2, pad1))
The idea is that instead of writing 2 separate functions, you factor out just the variables that change between the functions and create it as needed. touchTeleportTo creates a function that does the same as in your examples (with some changes), and uses the parameters source and destination to distinguish where to teleport the player.
Also, since touchTeleportTo returns the function when called, it’s called inside of the :Connect() as opposed to written as another function.
Other minor changes include switching the overarching if statement to a guard clause so that you don’t drop into an entire new scope. This is a bit cosmetic and up to you, but preferred in bigger functions.
I also made the assumption that you’d want your pad to not deactivate in the event that something without a humanoid touched it, so I moved the humanoid check into the guard clause too.
Lastly, to generalize the function I removed the padXEnabled variables. You could still add them inside the function creation, but it’s also one of those cosmetic things in this example.
This is exactly what I was going for, thanks so much! I’m still kind of stuck on the “return function(part)” because I’m not exactly sure what return does since I don’t use it much. I did not know you could pass parameters through the :Connect(), so it’s useful to know this in the future.
Well, not quite passing parameters through. return evaluates a function call into a value.
local function add(a, b)
return a + b
end
local result = add(1, 2)
print(result) -- 3
So what is actually happening, is a new anonymous function is being created, and that function is being returned. It might be clearer to see it this way:
local function touchTeleportTo(source, destination)
-- this creates a new instance of the function
local function anonymousHandler(part)
-- code
end
-- this makes calling `touchTeleportTo` evaluate to the new function
return anonymousHandler
end
local anonymousOnEvent = touchTeleportTo(pad1, pad2)
pad1.Touched:Connect(anonymousOnEvent)
The arguments pad1 and pad2 aren’t being passed to the event connector, they’re being passed to touchTeleportTo, which then generates a new function. The new function is then what is connected.
So, the return function(part) is essentially the Touched event portion like in my original, and the touchTeleportTo is outside of that listening for which pad is which? Also, I just searched up return and I saw that calling return inside a function will end it, which is why you did the if the statement and if any of the conditions were not met it ends.
Yes. The function(part) is what the event is connected to. touchTeleportTo is what creates that function based on which pads you want to teleport between.