Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
4

Touched not firing?

Asked by
ImageLabel 1541 Moderation Voter
9 years ago

I'm trying to execute the code in the while loop in correspondence with the value of "active". However, it isn't running. The script is indeed enabled, and script.Parent is indeed a BasePart..

local active, author = false

script.Parent.Touched:connect(function(hit)
  if pcall(function() return hit.Parent.Humanoid end) then
    local player = game.Players:playerFromCharacter(hit.Parent)
    active, author = true, player
  end
end)

script.Parent.TouchEnded:connect(function()
  active, author = false
end) -- edit

while active and wait() do
  warn(author, '\n')
end

Probably a silly error, but i can't seem to figure out what it is.

0
You're missing a closing parenthesis in this snippit. Where is it supposed to be? BlueTaslem 18071 — 9y
0
right before the while loop, TouchEnded connection. ImageLabel 1541 — 9y

1 answer

Log in to vote
3
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
9 years ago
Edited 7 years ago

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
            -- The part no longer exists, so forget about this player
            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.

0
makes, sense. Thanks. ImageLabel 1541 — 9y
Ad

Answer this question