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

TouchEnded Fails to Trigger?

I'm making an ocean floor where if you touch it, it slowly does damage until you stop touching it. The TouchConnected works fine, but when the player leaves it (TouchEnded), it occasionally fails to detect it, but also sometimes work (too inconsistent). What did I do wrong?

Here's the script to detect the player:

local CollectionService = game:GetService("CollectionService")
local selectedpart = CollectionService:GetTagged("OceanFloor")

for _, TaggedPart in pairs(selectedpart) do
	local active = false
	TaggedPart.Touched:Connect(function(hit)
		if not active then
			active = true
			local human = hit.Parent:FindFirstChild("Humanoid")
			if human then
				hit.Parent.TouchingSeaFloor.Value = true
			end
			wait(0.1)
			active = false
		end
	end)

	TaggedPart.TouchEnded:Connect(function(hit)
		if not active then
			active = true
			local human = hit.Parent:FindFirstChild("Humanoid")
			if human then
				hit.Parent.TouchingSeaFloor.Value = false
			end
			wait(0.1)
			active = false
		end
	end)
end

The script above will change the TouchingSeaFloor value to true or false, which is then handled by this, which appears to work.

local human = script.Parent:FindFirstChild("Humanoid")

if human then
	while true do
		if script.Parent.TouchingSeaFloor.Value == true then
			human.Health = human.Health - 10
			human.WalkSpeed = 8
		else
			human.WalkSpeed = 16
			script.Parent.TouchingSeaFloor.Value = false
		end
		wait(0.5)
	end
end

It's only the top script that fails to sometimes change the TouchingSeaFloor value to false when the player stops touching the sea floor.

Nothing I found seemed to work, so any help would be appreciated :)

2 comments

0

you need something to break that while look (litearlly the code "break") and TouchEnded fires right after Touched gets fired

0

@Gameplayer365247v2 It doesn't work, just makes it more buggy. Any other ideas? Or maybe I just did it wrong?

1 answer

✓ Accepted answer

this is because of 1. your debounce and 2. the fact that your character's limbs are constantly bouncing around on the part

you can see it here (seizure warning maybe), the part changes color whenever Touched or TouchEnded fires

obviously with all your limbs being animated and jumping up and down, Touched and TouchEnded are going to fire a lot, so that's part of the reason why you might have been taught to use a debounce with Touched

however, with TouchEnded firing so rapidly, it has a chance to be caught in the middle of the debounce when your character actually does leave

removing the debounce would fix the problem with inconsistency, but it would also cause everything to start acting up a bit, so what we can do in addition to that is add an external hitbox that wraps around the entire character, and only change the TouchingSeaFloor value if that hitbox is what touched or stopped touching the sea floor

for the hitbox, you can put a part in StarterCharacterScripts (yes, i said StarterCharacterScripts; although it's called "scripts", you can put anything in there and it'll be cloned into the character when they spawn, so it's a convenient way to not have to clone things manually), and then make it uncollidable, unanchored, transparent, and massless. make sure that it has a unique name too, because you'll need to reference it in your Touched script

for the size, you want the hitbox to be a bit thicker and taller than the entire character; i'd use a size like [3, 8, 3] but you can change it up a bit depending on how tall or how wide your character is

now that you have the hitbox, you can parent a simple script to it that welds it to the character's HumanoidRootPart

local char = script.Parent.Parent
local weld = Instance.new("Weld")
weld.Part0 = char:WaitForChild("HumanoidRootPart")
weld.Part1 = script.Parent
weld.Parent = script.Parent

so now you have a hitbox that follows your character around and can be used to detect when the player touches the sea floor

now you just have to make a few modifications to your Touched script so that it only detects the hitbox and doesn't have a debounce

local CollectionService = game:GetService("CollectionService")
local selectedpart = CollectionService:GetTagged("OceanFloor")

for _, TaggedPart in pairs(selectedpart) do
    local active = false
    TaggedPart.Touched:Connect(function(hit)
        local human = hit.Parent:FindFirstChild("Humanoid")
        if hit.Name == "Hitbox" and human then -- it doesn't have to be named "Hitbox", but just make sure it has a name that won't clash with anything else
            hit.Parent.TouchingSeaFloor.Value = true
        end
    end)

    TaggedPart.TouchEnded:Connect(function(hit)
        local human = hit.Parent:FindFirstChild("Humanoid")
        if hit.Name == "Hitbox" and human then
            hit.Parent.TouchingSeaFloor.Value = false
        end
    end)
end

now that we're only detecting the hitbox, you can see that Touched or TouchEnded only fires when the character actually touches or leaves the part

6 comments

0

I made the hitbox, dragged it into the StarterCharacterScripts, changed all the settings, then copied and pasted the weld script into it. The part doesn't show up (it just disappears) when I drag it into the StarterCharacterScripts, and when I start, I couldn't find the welded part in the character and the script doesn't work. What did I do wrong?

0

are you sure there aren't any other scripts that might be interfering with it

0

also, did you make it a Script or a LocalScript

0

Don't know, the part just doesn't show up and becomes invisible when I put it in StarterCharacterScripts, even with transparency to 0. Can you give me the example project you made in the video so I can check to see if I did everything correctly?

0

Thanks, it worked now. Turns out I had a part that was also called hitbox which was messing with it lol

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