There's no reason to have separate author and active variables, since active will always be the same as author ~= nil.
You shouldn't use pcall to do work for you. It's slow, complicated, and confusing. Write code that doesn't error instead of trying to cover it up. In this case, it's really, really easy to avoid that code:
local touching = nil
script.Parent.Touched:connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
touching = player
end
end)
Your code was missing a closing paren after the end on line 12.
script.Parent.TouchEnded:connect(function()
touching = nil
end
The final while loop has a problem. Whenever touching became false, the loop would stop -- and not resume. If you want to something "whenever active is true" you have to loop forever and check if touching then:
while wait() do
if touching then
print(touching, "is touching me")
else
print("no one is touching me")
end
end
There are a few caveats to this overall design:
- Two players can't be touching it at the same time
- If any part, not just the touching player stops touching the button, this stops
Both of these are a little difficult to solve.
You can more or less solve them using dictionaries:
local touching = {}
script.Parent.Touched:connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
touching[player] = true
end
end
script.Parent.TouchEnded:connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
touching[player] = nil
end
end
Instead of having a single "touching", we save the state more or less for all players using a dictionary.
You can get all of the players currently touching with a generic for loop:
while wait() do
for player in pairs(touching) do
print(player, "is touching")
end
end
One problem with this is if the TouchEnded event doesn't fire. I believe this will happen if, for instance, the player leaves or despawns. It would be safest to also ensure that the original part survived. Thus, instead of using true, we'll save hit:
script.Parent.Touched:connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
touching[player] = hit
end
end
and we'll delete "dead" touches in the loop:
for player, part in pairs(touching) do
print("player is touching")
if not part.Parent then
touching[player] = nil
end
end
This is still a little lacking -- if you stand on the button with one leg, and the other brushes against it, that TouchEnded will say you are no longer pressing the button. Ideally, we would only worry about the final touch.
We could use a dictionary, or just keep track of a count, adding 1 for a touch and subtracting for a touch ended.
2 comments
You're missing a closing parenthesis in this snippit. Where is it supposed to be?
right before the while loop, TouchEnded connection.