Hi, I’m @RuizuKun_Dev!
Today I’ll be addressing the reliability issue when using TouchEvents, it’s not as unreliable as you think.
Sure you can use Region3, Raycast, GetTouchingParts or Magnitude instead however those are quite tedious and complex compared to TouchEvents.
and I’ll be showing you the reason why TouchEvents are unreliable is because of your Implementation not Roblox
How it works
Normal Implementation
Touched & TouchEnded fires when touchedPart starts Touching and stops Touching detectorPart
Special case:
- When you Equip/Unequip a Tool Touched & TouchEnded fires
- When you change the Character size Touched & TouchEnded fires
These are probably why TouchEvents to seems to be unreliable
The Problem
- Detecting the entire Player.Character with no Touch Filters
- Not checking if the touchedPart is still inside the detectorPart
- Not knowledgeable of how TouchEvent works (due to lack of Documentation)
How to use it Properly
My Implementation
You need to be Detecting Touch on ONLY one Part at a time for Player.Character, which is preferably the HumanoidRootPart
and to prevent those special cases from causing trouble we need to check if the touchedPart is still inside that detectorPart
you can also Connect and Disconnect the TouchEvents for efficiency
Source Code
Code
--| SERVICES:
local plr = game.Players.LocalPlayer
local Cha = plr.Character
local Hum = Cha.Humanoid
local RootPart = Hum.RootPart
--| VARIABLES:
local Red = Color3.new(1,0,0)
local Green = Color3.new(0,1,0)
local USE_NORMAL_IMPLEMENTATION = false
local detectorPart = workspace.Part
--| FUNCTIONS:
local function isPointInPart_Fn(Point, Part)
local relPos = Part.CFrame:PointToObjectSpace(Point)
return math.abs(relPos.X) < Part.Size.X*.5 and math.abs(relPos.Y) < Part.Size.Y*.5 and math.abs(relPos.Z) < Part.Size.Z*.5
end
-- Implementations
--|> Normal Implementation
local function NormalImplementation()
detectorPart.Touched:Connect(function(touchedPart)
if touchedPart == RootPart then
print(".Touched")
RootPart.Color = Green
end
end)
detectorPart.TouchEnded:Connect(function(touchedPart)
if touchedPart == RootPart then
print(".TouchEnded")
RootPart.Color = Red
end
end)
end
--|> My Implementation
local function MyImplementation()
local IsInPart
local touched_Fn, touchEnded_Fn
local touched_Ev, touchEnded_Ev = detectorPart.Touched, detectorPart.TouchEnded
local touched_Connection, touchEnded_Connection
-- touched
function touched_Fn(touchedPart)
if (not IsInPart) and touchedPart == RootPart then
IsInPart = true
touched_Connection:Disconnect()
touchEnded_Connection = touchEnded_Ev:Connect(touchEnded_Fn)
print(".Touched")
RootPart.Color = Green
end
end
-- touchEnded
function touchEnded_Fn(touchedPart)
if IsInPart and touchedPart == RootPart then
if (not isPointInPart_Fn(RootPart.Position,detectorPart)) then
IsInPart = nil
touchEnded_Connection:Disconnect()
touched_Connection = touched_Ev:Connect(touched_Fn)
print(".TouchEnded")
RootPart.Color = Red
end
end
end
touched_Connection = touched_Ev:Connect(touched_Fn)
end
--| SCRIPTS:
if USE_NORMAL_IMPLEMENTATION then
NormalImplementation()
else
MyImplementation()
end
for _,v in ipairs(Cha:GetDescendants()) do
if v:IsA("BasePart") then
v.Transparency = .9
end
end
Cha.DescendantAdded:Connect(function(addedDescendant)
if addedDescendant:IsA("BasePart") then
addedDescendant.Transparency = .9
end
end)
RootPart.Transparency = 0
Cha.Head.face:Destroy()
Resouces
- Uncopylocked:
https://www.roblox.com/games/5291675075/TouchEvents