TouchEnded does not work correctly. Why?

Hello,

I’m on a test map, and I wanted to test a certain script. The goal is to randomly change the color once, then when the player leaves and comes back, change the color once again.

The problem: The TouchEnded event doesn’t work properly: it activates at the same frequency as the Touched event, even though I’m not moving. My script can’t work.

I’ll give you the code and a video, thanks for your help!

local part = script.Parent
local debounce = false

part.Touched:Connect(function(hit)
	local humanoid = hit.Parent:FindFirstChild("Humanoid")
	if debounce then return end
	if humanoid then
		debounce = true
		part.Color = Color3.new(math.random(0, 255), math.random(0, 255), math.random(0, 255))
	end
end)

part.TouchEnded:Connect(function(hit)
	local humanoid = hit.Parent:FindFirstChild("Humanoid")
	if humanoid then
		if debounce then
			wait()
			debounce = false
		end

	end
end)

Thanks.

Do you just want the script to change the color once when touched and not multiple time?

That’s right. So if the player stays on the share, the color stays the same. But when he leaves and then returns, the color changes once again.

Try to wait 1 second before set the debounce in the TouchEnded event

By doing this, the color changes only once, but after 1 second, it starts changing again every millisecond.

Ok, so if you want to check if the player touch and bot touching the part more accurate I wouldn’t suggest u to use Touch and TouchEnded event because those two are quite buggy. So what I’m thinking is that you should use a module name ZonePlus to achieve what u want here. The ZonePlus module allow you to check if player touched or leave the object more accurately since it use OverlapParams. This is my solution. But, if someone got better way to do this then go ahead I won’t stop you.

1 Like

Multiple body parts will make and lose contact with the part throughout the movement and animation of the character. You’ll need to ensure all body parts pertaining to a particular character are no longer in contact with the part before allowing that player to trigger another colour change. I recommend making a function that utilizes Workspace:GetPartsInPart and Instance:IsDescendantOf to check if any colliding parts belong to the particular character. You could also generate an OverlapParams instance at the time of initial contact, set its FilterDescendantsInstances to the character in question, and switch the FilterType to “Include”. This will return an empty array when no colliding parts belong to that character. De-cache the OverlapParams object when Instance.TouchEnded turns up no remaining collision with the character

2 Likes

That’s overkill for OP’s situation

1 Like

Yes. Ik is overkill. But it is better than nothing right?

Also, ZonePlus already do all the work for you so that u don’t have to setup your own spatial query. All u do is require the module then use what it provide you. It would save his time more.

That’s like asking OP to use a car to go down the street instead of their own two legs

Imma let the OP decide what to do. Is not our choice.

Setting up a helper function or spatial query with cached OverlapParams is not a complicated endeavour. In fact, the time it takes to implement either would be less than the time it takes to install and configure ZonePlus to OP’s situation. Both of my proposed solutions are taking the fundamental components of a bulky spatial querying tool for a less nuanced goal

Ok, sure. OP can go your way if it is better than mine.

This happens because your rig has multiple parts, and TouchEnded signal fires when one of your rig’s part stops touching it most likely due to animations.

Using TouchEnded in this situation is not a good method to do this. Instead, you should likely use the magnitude between the part and the player

2 Likes

I’ll try to use this method first. In what situations will we use these methods?

I finally succeeded in checking the magnitude. Thanks all the same for the help, I learned several things thanks to you 3.

local part = script.Parent
local debounce = false
local distance

part.Touched:Connect(function(hit)
	local humanoidRootPart = hit.Parent:FindFirstChild("HumanoidRootPart")
	if humanoidRootPart then
		distance = (humanoidRootPart.Position - part.Position).Magnitude

		if distance <= 5 and not debounce then
			debounce = true
			part.Color = Color3.new(math.random(), math.random(), math.random())
		end
	end
end)

game:GetService("RunService").Heartbeat:Connect(function()
	if distance and distance > 5 and debounce then
		debounce = false
	end
end)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.