Touch event not firing correctly

I’m a begginer at coding in lua, so I made a map to learn and get better. The problem now is that I have a part that should damage the player if touched. It should disappear (not deal damage)
and then appear (now dealing damage). The disappear and appear loop works, and it deals damage, but not properly;

It damages me when I walk through it

1

But if I stand still (or move really slowly) it does nothing

2

This is an error that shows sometimes, like its looking for the humanoid inside the accesory, don't know why

error

It seems that using the “touch” event isn’t a good option, but i’ve searched for a fix and haven’t found anything really useful nor simple.

The code:

local part = script.Parent
local canDmg = true

local function damage(otherPart)
	if canDmg == true then
		local partParent = otherPart.Parent
		local hum = partParent.Humanoid
		if hum then
			hum.Health -= 1
		end
	end
end

local function disappear()
	part.Transparency = 1
	canDmg = false
end

local function appear()
	part.Transparency = 0.7
	canDmg = true
end

part.Touched:Connect(damage)

while true do
	disappear()
	wait(3)
	appear()
	wait(3)

end
1 Like

How about checking if the touched part.Parent has a Humanoid?

2 Likes

Check to see if there is a humanoid:

part.Touched:Connect(function(hit)
    if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
        -- do the thing
    end
end)
1 Like

Try doing:

local hum = partParent:FindFirstChild("Humanoid")
if not hum then return end
if hum then
    hum.Health -= 1
end

Also, maybe move the damage function right below the appear function, see if that’ll work

2 Likes

I’ve put that in the code, but appearently it still works the same

new code:

local part = script.Parent
local canDmg = true

part.Touched:Connect(function(hit)
	if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
		if canDmg == true then
			local partParent = hit.Parent
			local hum = partParent.Humanoid
			if hum then
				hum.Health -= 1
			end
		end
	end
end)

local function disappear()
	part.Transparency = 1
	canDmg = false
end

local function appear()
	part.Transparency = 0.7
	canDmg = true
end

while true do
	disappear()
	wait(3)
	appear()
	wait(3)

end
1 Like

Where are appear() and disappear() being called?

1 Like

also you should do

hum = hit.Parent:FindFirstChild("Humnoid")

to check for hum.

1 Like

The problem is that you are still in touch with the part. You should try to check when the touch is ended to determine whether you are still in touch with the part or not (hence BasePart.Touched and BasePart.TouchEnded).

It makes perfect sense for your code not to work, since BasePart.Touch will only fire when a part collides into another part for the first time.

1 Like
local part = script.Parent
local canDmg = true
local Cooldown = false

local function damage(otherPart)
    local Player = game.Players:GetPlayerFromCharacter(otherPart.Parent) --This will check that we do have a Character that touched the part or not
	if canDmg and Player and not Cooldown then
        Cooldown = true

		local Character = otherPart.Parent
        local Humanoid = Character:FindFirstChild("Humanoid")

        if not Humanoid then
            return
        end

        Humanoid.Health -= 1
        wait()
        Cooldown = false
	end
end

local function disappear()
	part.Transparency = 1
	canDmg = false
end

local function appear()
	part.Transparency = 0.7
	canDmg = true
end

part.Touched:Connect(damage)

while true do
	disappear()
	wait(3)
	appear()
	wait(3)
end

Here’s a better implementation with a couple more sanity checks, also I’d recommend adding a debounce to prevent the script from actually KILLING the Character from firing so much Events at once

1 Like

Using this code it works the same.

Placing the damage code after the appear code makes it not work. The part appears and disappears, but the damage isn’t dealt

1 Like

I think I get what @goldenDiamondber’s issue is now. You should use a variable to define whether or not the player is touching it, and use touched, and touchEnded to change the variable.

touchended:Connect(function()
istouching = false
)

touched:Connect(function()
istouching = true
)

while true do
wait()
if istouching then
-- do damage
else
-- dont do damage?
end
end

very rough draft right there, but hopefully that will give you an idea.

2 Likes

Replied to the wrong comment, oops lol.

1 Like

You could make sure that the function isn’t after the part.Touched:Connect(damage)
But it might not work either way i guess, so

1 Like

I understand. So it fires when I enter in contact with the part, but it won’t continue dealing damage because I’m already in contact with it. But what should I do to make it CONTINUE with the damage, after taking it in the first place?

2 Likes

That is correct. I do not really have the time to write something right now, but you can keep track of what parts are in touch with your damaging part. Then you can see what humanoids they belong to and deal damage.

1 Like

For how you are doing this, I recommend using Region3 instead of Touched events. The reason why you don’t deal damage when you stand still is because touched events only work for the first touch. I assume you could use a value and TouchEnded so it keeps damaging the player until they stop touching if you want to stick with how you are doing it.

When the part appears and disappears you can also mess with that same value to see if the part can damage the player or not.

3 Likes

I think there is a bug with BasePart.Touched event.

1 Like

That is not a bug, since your player is made of multiple parts.

2 Likes

this is exacly what happens lol

1 Like

That’s why the touch event isnt that good then. I’ve seen a video abou the Region3, but when trying on my place it didn’t work, so I just tried using touch on my own.

1 Like