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

How would I make this fix simpler to a ontouch problem involving the player?

Asked by
UPumpkin -34
5 years ago

So basically I have this

local cd = false

function onTouched(hit)
if cd == false then
cd = true   
game.Players[hit.Parent.Name].leaderstats.Coins.Value = 1
wait(0.3)
cd = false  
end

end

script.Parent.Touched:connect(onTouched)

The goal of this is that when the part is touched the player's coins turn to 0

but if a accessory touches it rather then the persons body part the script could break

How would I make a fix for this rather then doing

if hit.ClassName == "Part" then

is there a simpler way to do it?

0
that's pointless User#19524 175 — 5y
0
lmao greatneil80 2647 — 5y

3 answers

Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

Yes there is another way to do it. It is how you're defining your player.

local canTouch = true

local function onTouched(hit)
    if canTouch then
        canTouch = false

        local humanoid = hit.Parent:FindFirstChild("Humanoid") or hit.Parent.Parent:FindFirstChild("Humanoid")
        if humanoid then
            local character = humanoid.Parent
            local player = players:GetPlayerFromCharacter(character)

            if player then
                player.leaderstats.Coins.Value = 0
            end
        end

        wait(0.3)
        canTouch = true
    end
end

Now you may be asking "Well how exactly does this work?"

First we define the humanoid; we use ternary operators in our favor. In a statement such as a = b or d it will set a to which variable has truthiness, if both have truthiness then it is set to d (If you do not know what truthiness is I suggest looking at this article Truthy, and this Expressions Tutorial)

Now we check if the humanoid actually exists :FindFirstChild() returns the instance or nil if it does not exist, so if humanoid exists then continue code.

Now we know that the parent of a humanoid will be the player's (or NPC's) physical character model. Having reference to their character allows us to use the :GetPlayerFromCharacter() method which returns the player that owns that character model. This can be nil and it will only be nil if the player is not found. We use :GetPlayerFromCharacter() and not players[character.Name] because the humanoid that touched the brick might be a NPC in the game, which have no player instance in the players service.

Finally if the player exists, then index their leaderstats, then their coins, and set the value to 0

Ad
Log in to vote
0
Answered by
Pojoto 329 Moderation Voter
5 years ago

Yes, I recommend checking if hit is a player.

local cd = false

function onTouched(hit)

    local character = hit.Parent
    local humanoid = character:FindFirstChild("Humanoid")

    if humanoid then
        if cd == false then
            cd = true   
            local player = game.Players:GetPlayerFromCharacter(character)
            player.leaderstats.Coins.Value = 1 -- or 0
            wait(0.3)
            cd = false  
        end
    end
end

script.Parent.Touched:connect(onTouched)

Basically, we're checking for if the part that touched it has something in it called a Humanoid. If it does, then we know it's a player and we can run the code. If it's not then it won't check through the if humanoid then statement and pass through.

This way, if an accessory or something else hit it, it wouldn't run the code.

I also made a variable called player, so we can get the player who touched it easier by using GetPlayerFromCharacter which does what it says :P

Log in to vote
0
Answered by 5 years ago

I'm a fan of using dictionaries to create player unique debounces, which would look something like this.

local CooldownTime = 10

local Players = game:GetService('Players')
local PlayerUniqueCooldown = {}

script.Parent.Touched:Connect(function(Part)
    local Player = Players:GetPlayerFromCharacter(Part.Parent)
    if not Player then return end
    if PlayerUniqueCooldown[Player] then return end
    PlayerUniqueCooldown[Player] = true
    local Leaderstats = Player:FindFirstChild('leaderstats')
    if not Leaderstats then return end
    local Coins = Leaderstats:FindFirstChild('Coins')
    if not Coins then return end
    Coins.Value = Coins.Value + 1
    wait(CooldownTime)
    PlayerUniqueCooldown[Player] = nil
end)

Answer this question