.Touched not called sometimes

Hello! I’m currently making a game, where some selected preset is falling down onto the players’ heads. I’m tweening the preset on the Client, I used to do it on Server, and I had script inside the Preset, getting .Touched event, to kill the players, if they touch it. But now I ported it onto the client, can I still use that script or is it unsafe? (Exploiter can delete the preset on his side, and the round would never end.) Well, I tried making a Server script then, it works well, but when it gets faster, it is not getting .Touched sometimes. (I’m giving the script 0.25 time to do it, don’t know If that is the problem.) The method I use is that I make the same preset, slightly above the ground. The script looks like this:

function CloneToucher(Preset)
	local Toucher = Preset:Clone()
	Toucher.Parent = workspace
	Toucher.Name = "Toucher"
	local Welder = ServerStorage.Welder:Clone()
	Welder.Parent = Toucher
	Welder.Name = "Welder"
	local Script = ServerStorage.ToucherScript:Clone()
	Script.Parent = Toucher
	Script.Name = "ToucherControl"
	Script.Disabled = false
	Toucher.PrimaryPart.CFrame = CFrame.new(0,1.5,0)
	for i, part in pairs(Toucher:GetChildren()) do
		if part:IsA("BasePart") then
		part.Transparency = 1
		elseif part:IsA("Script") then
			if part.Name == "ExampleScript" then
				part:Destroy()
			end
		end
	end
end

The ToucherControl script:

local db = {}
for i, part in pairs(script.Parent:GetChildren()) do
	if part:IsA("BasePart") then
		if part.Name == "SkyPiece" then
		part.Touched:Connect(function(hit)
			if game.Players:GetPlayerFromCharacter(hit.Parent) then
				local player = game.Players:GetPlayerFromCharacter(hit.Parent)
				if player and db[player] ~= true  and player.Character.Humanoid.Health > 0 then
					db[player] = true
					print("Touched")
					game:GetService("ReplicatedStorage").PlaySound:FireClient(player, workspace.Sounds.Hit)
					if player.leaderstats.Lives.Value > 1 then
						player.leaderstats.Lives.Value = player.leaderstats.Lives.Value - 1
						game:GetService("ReplicatedStorage").Blink:FireClient(player)
						wait(1)
						db[player] = false
					elseif player.leaderstats.Lives.Value == 1 then
						player.leaderstats.Lives.Value = player.leaderstats.Lives.Value - 1	
						wait(1)
						db[player] = false
						end
					end
				end
			end)
		end
	end 
end

This has 0.25 seconds to execute, I delete it after. Could this be the problem?

EDIT: It works during slower rounds, but bug in faster rounds.

1 Like

What script are you deleting?

I think yes, bec when you speed it up, there will be more presents, so more script executing on same time, so slower run.

I’m deleting the whole Toucher, thus the script too. (The ToucherControl one)

If the parts are moving downwards, and downwards only, could you possibly raycast every Heartbeat in the direction of the ground?

Raycasting is highly faster than Touched and provides some helpful information (like where it intersects).
The ray will need to be small though, as you don’t want players randomly getting hit.

Here’s some code code to get you kick started:

--// Dependencies
local RunService = game:GetService("RunService")
--// Variables
local KeepRaycasting = true --// Boolean for if it should continue raycasting
local GroundY = 0 --// The Y position of the ground

while KeepRaycasting do
    local ray = Ray.new(part.Position, (part.Position - Vector3.new(part.Position.X, GroundY, part.Position.Z)).Unit * 3) --// Make a Unit ray multiplied by 3 in the direction of the ground from the part
    local hitPart, hitPosition = workspace:FindPartOnRay(ray, part)
    --// Now you can do the checking, debouncing, damaging etc
    RunService.Heartbeat:Wait()
end
2 Likes