.Touched and .TouchEnded being weird

As the title says, anyway to fix this problem?
https://gyazo.com/dcb14b640cea6779efe62c6239e56828

TouchEnded can be unreliable in a lot of Instances

Some alternates you could use, is by using Region3 which takes a specific region you want to detect and if the Player is close enough you can make the part visible

Another one would be using Magnitude, which takes the Distances between 2 Parts & you can check if the Part is close enough to make it visible

Could you post your code as well?

How would I use Region3 in this case? I never used Region3

For the first part

script.Parent.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
	workspace.Part2.Transparency = 1
	workspace.Part2.CanCollide = false
	end
end)

script.Parent.TouchEnded:Connect(function(hit)
	workspace.Part2.Transparency = 0
	workspace.Part2.CanCollide = true
end)

for the second part

script.Parent.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
	workspace.Part1.Transparency = 1
	workspace.Part1.CanCollide = false
	end
end)

script.Parent.TouchEnded:Connect(function(hit)
	workspace.Part1.Transparency = 0
	workspace.Part1.CanCollide = true
end)
1 Like

I believe the problem may have to do with TouchEnded being triggered multiple times by both legs. But I’m not sure why it would flicker more than once or twice. But like @JackscarIitt said, the Touch events are very unreliable.

First we’d wanna get our Part’s Max/Min Size variables

local Part1Min = workspace.Part1.Position - (0.6 * workspace.Part1.Size)
local Part2Min = workspace.Part2.Position - (0.6 * workspace.Part2.Size)

local Part1Max = workspace.Part1.Position + (0.6 * workspace.Part1.Size)
local Part2Max = workspace.Part2.Position + (0.6 * workspace.Part2.Size)

These will set the minimal & maximal sizes of our parts we want to detect before we start our loop

Next, say we could implement this in a while true do loop:

local Part1Min = workspace.Part1.Position - (0.6 * workspace.Part1.Size)
local Part2Min = workspace.Part2.Position - (0.6 * workspace.Part2.Size)

local Part1Max = workspace.Part1.Position + (0.6 * workspace.Part1.Size)
local Part2Max = workspace.Part2.Position + (0.6 * workspace.Part2.Size)

local RunService = game:GetService("RunService")

local Region1 = Region3.new(Part1Min, Part1Max)
local Region2 = Region3.new(Part2Min, Part2Max)

while true do
    local PartCheck1 = workspace:FindPartsInRegion3(Region, workspace.Part)
    local PartCheck2 = workspace:FindPartsInRegion3(Region2, workspace.Part2)

    RunService.Heartbeat:Wait()
end

We’re creating our Regions (Or 3d spaces to how far we want the parts to expand from), and we’ll use a RunService event so that it’ll wait every so frequently

And FindPartsInRegion3 would return an array (Or group of parts that’ll be returned back)

Since we’re wanting to check if the player inside the Region is close enough, we can put our PartCheck1 & PartCheck2 variables through a for loop:

local Part1Min = workspace.Part1.Position - (0.6 * workspace.Part1.Size)
local Part2Min = workspace.Part2.Position - (0.6 * workspace.Part2.Size)

local Part1Max = workspace.Part1.Position + (0.6 * workspace.Part1.Size)
local Part2Max = workspace.Part2.Position + (0.6 * workspace.Part2.Size)

local RunService = game:GetService("RunService")

local Region1 = Region3.new(Part1Min, Part1Max)
local Region2 = Region3.new(Part2Min, Part2Max)

while true do
    local PartCheck1 = workspace:FindPartsInRegion3(Region, workspace.Part)
    local PartCheck2 = workspace:FindPartsInRegion3(Region2, workspace.Part2)

    for _, Part in pairs(PartCheck1) do
        if game.Players:GetPlayerFromCharacer(Part.Parent) then
            workspace.Part2.Transparency = 0
            workspace.Part2.CanCollide = true
        else
            workspace.Part1.Transparency = 1
            workspace.Part1.CanCollide = false
        end
    end

    for _, Part in pairs(PartCheck1) do
        if game.Players:GetPlayerFromCharacer(Part.Parent) then
            workspace.Part1.Transparency = 0
            workspace.Part1.CanCollide = true
        else
            workspace.Part2.Transparency = 1
            workspace.Part2.CanCollide = false
        end
    end
    RunService.Heartbeat:Wait()
end

Maybe you could implement something like this but I’m very small on how Region3 works so

2 Likes

Here’s a simplified version of that using a touched event:

local part = script.Parent
local touching
local y = part.Position.Y+part.Size.Y/2
local region = Region3.new(Vector3.new(part.Position.X-part.Size.X/2,y,part.Position.Z-part.Size.Z/2),Vector3.new(part.Position.X+part.Size.X/2,y+1,part.Position.Z+part.Size.Z/2))
part.Touched:Connect(function(hit)
	if not touching and hit.Parent:FindFirstChild('Humanoid') then
		touching = true
		part.Transparency = 0
		repeat
			game:GetService('RunService').Heartbeat:Wait()
			if #workspace:FindPartsInRegion3(region,part) == 0 then
				part.Transparency = 1
				touching = false
			end
		until not touching
	end
end)

Sadly, the touch event is still unreliable and sometimes won’t trigger when jumping in place. I only used the touch event so that the loop only runs when needed, but you can have it loop permanently for more accuracy. But for that, I would recommend using a single loop for every part that you want to do the same thing in one single script.

4 Likes

@MightyDantheman 's worked for me and @JackscarIitt 's didn’t sadly.
If possible can I have an explanation of how it worked?

local part = script.Parent
local touching --To avoid more than one loop at a time
local y = part.Position.Y+part.Size.Y/2 --To get the Y axis of the top of the part
local region = Region3.new(Vector3.new(part.Position.X-part.Size.X/2,y,part.Position.Z-part.Size.Z/2),Vector3.new(part.Position.X+part.Size.X/2,y+1,part.Position.Z+part.Size.Z/2)) --Creates the region with the same witdth as the part, but 1 stud tall. The position is 1 stud above the part.
part.Touched:Connect(function(hit)
	if not touching and hit.Parent:FindFirstChild('Humanoid') then
		touching = true
		part.Transparency = 0
		repeat
			game:GetService('RunService').Heartbeat:Wait()
			if #workspace:FindPartsInRegion3(region,part) == 0 then --Checks to make sure there are 0 parts within the given region, ignoring the part itself.
				part.Transparency = 1
				touching = false --End the loop of no more touching parts.
			end
		until not touching
	end
end)

I’m not sure if that helps any, but feel free to ask if you have any more specific questions.

1 Like