Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

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

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?

2 comments

0

that's pointless

0

lmao

3 answers

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

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

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)

This discussion is preserved as it was. New answers, comments, and votes are closed.