I’ve been planning my own proximity system and had problems with touched events that I can only explain as twitching. Visually, it looks to work as intended, but I noticed that the parts get disconnected unexpectedly. Touchended and touched are fired in rapid succession, all in a single render cycle. This happens both when I press and release the spacebar to jump, and sometimes as I run around the object.
Since it’s fired so fast, changes can’t be seen unless you print to the console.
It’s set to weld a sphere around the player when they load.
local root = game.Players.LocalPlayer.CharacterAdded:Wait():WaitForChild("HumanoidRootPart")
local prox = Instance.new("Part")
prox.CanCollide = false
prox.CastShadow = false
prox.Massless = true
prox.Material = Enum.Material.ForceField
prox.Position = root.Position
prox.Shape = Enum.PartType.Ball
prox.Size = Vector3.new(32, 32, 32)
prox.Parent = workspace
local weld = Instance.new("WeldConstraint")
weld.Part0 = prox
weld.Part1 = root
weld.Parent = workspace
So instead of attaching to events like this:
prox.Touched:Connect(function (hit)
if hit.Name == "Trigger" then
print("Touched "..hit.Name)
hit.Material = Enum.Material.Neon
end
end)
prox.TouchEnded:Connect(function (hit)
if hit.Name == "Trigger" then
hit.Material = Enum.Material.Plastic
end
end)
I’ve had to resort to something a bit more complicated.
local touches = {}
local function WhatWeWant(obj) return obj.Name == "Trigger" end
prox.Touched:Connect(function (hit)
-- Check requirements
if not WhatWeWant(hit) then return end
if touches[hit] then
-- Twitch detected
touches[hit] = touches[hit] + 1
return
else
-- Initialize count
touches[hit] = 1
end
-- Begin touch
print("Touched "..hit.Name)
hit.Material = Enum.Material.Neon
end)
prox.TouchEnded:Connect(function (hit)
-- Check requirements
if not WhatWeWant(hit) then return end
-- Give time to twitch
wait()
-- Adjust touch count
touches[hit] = touches[hit] - 1
-- Sink all but last event
if 0 < touches[hit] then return end
-- Reset touches
touches[hit] = nil
-- End touch
print("Touchended "..hit.Name)
hit.Material = Enum.Material.Marble
end)
Download the place here. There are two scripts located in ReplicatedStorage, basic and fixed, but the one named basic is disabled.
Is this the best way to go about this or am I missing something?