.Touched RBXScriptSignal seems to be delayed

Hello,
I am in need of some help for a game I am releasing soon with Beast Games. It is some very bare basic code for a simple jump obby with no killparts or anything. It is an anchored part with a .Touched event connected to it. There are 5 scripts (not including DataStore2).

script.Parent.Ground.Touched:Connect(function(hit)
	print("Ground touched.")
	local plr = game.Players:GetPlayerFromCharacter(hit.Parent)

	if (plr ~= nil) then
		print("Player is not nil")
		plr.Character:SetPrimaryPartCFrame(game.Workspace.Elevator.TeleportPart.CFrame)
	end
end)

This is what happens:
The line before the plr variable is defined, the print statement is printed at the same exact time it prints Player is not nil

I can go on the platform and move around, but as soon as I stop it prints both of them. (could be a roblox bug :thinking:)
Here is a gif showing it.
You can slow it down if you want.
https://gyazo.com/f2642b8ef950cbf5f4043f463760c21d
(I am not sure why, but it does not embed when I click Upload)

1 Like

The reason why it prints really fast is because it fires when the part is touched. You didnt make the script yield after the print therefore after the print it checks if the player is nil, and if it is nil then it prints. If statements dont take like 2 minutes to check, it only takes like a few miliseconds.

You should also add a debounce. When you move around it doesnt fire because its being touched too much, and when you stop it fires for the one last time. You might see little numbers with an x behind it in the print statements. That means how many of the same prints were fired.

I don’t think you saw correctly. I’m saying that it prints after my character comes to a complete stop. I know what a debounce is, and the problem is it is DELAYED.

Is that being run on a normal script? Try a local script and it should be faster as that will run client side.

Well uh, I’m not gonna do that. The client can easily destroy the script and destroy the purpose of the script

You could have both the client and the server script as backup.
You won’t get past a delay from the server easily as the client has to wait for the server to recognise a collision and spend time relaying that information back to the client that must now teleport.

.Touched events fired with client owned parts are no different than localscripts. Clients can destroy the TouchTransmitter easily.

I’m pretty sure they both print at the same time because both conditions are met.

This is printed because the part is touched.

This is also valid. If plr is not equal to nil, then print. When you touch the part plr is not equal to nil.

That is true, but if you were to actually look at the gif, it doesn’t print UNTIL I stop moving at all. That is not normal.

.Touched is often unreliable, which is why I don’t really use it nowadays. You’re better off just either using magnitude to see if the player got close to the part, and is almost touching it, or Region3.

I suggest using Zone+ module by ForeverHD for handling touchevents.

I use while true do for .Touched events. (Not always)

also you can use .TouchEnded.

But I don’t like using .Touched events anymore. It’s unstable and not reliable.
I prefer .magnitude.

An exploiter deleting a script that allows basic character teleporting is the least of your concerns, they can teleport themselves to anywhere if done correctly.

@TalonMidnight That is true, but I am talking about that there seems to be a bug with Roblox’s LUA.

@ANDROHERSEY00 that is bad for memory.

@FastAsFlash_Dev I’ve used that before and I am using it but I just need a simple .Touched event to work like normal.

There just seems to be a problem with the event registering, maybe a recent update broke it a bit. BECAUSE:
When I move around on the part, nothing happens
BUT
when I stop moving then it works.

This might not be ideal, but you can go through the part’s touching parts (using GetTouchingParts) in a loop and if any of the touching parts is a player then teleport them.

while wait() do
    local Parts = script.Parent.Ground:GetTouchingParts()

    for _, Part in pairs(Parts) do
        local plr = game.Players:GetPlayerFromCharacter(Part.Parent)

        if plr then
            plr.Character:SetPrimaryPartCFrame(game.Workspace.Elevator.TeleportPart.CFrame)
        end
    end
end

Did you try making the lava uncollidable? IIRC the Touched event only picks up intersection of parts but not surface collision.

That shouldn’t be happening even if the touch event is usaually unreliable. This happened to me once because my position on the server was different from my position on the client when I teleported the HumanoidRootPart by position instead of CFrame. Try checking on the server if the position is same as the client.

script.Parent.Ground.Touched:Connect(function(hit)
print("Ground touched.")
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)

if plr then
	print("Player is not nil")
	plr.Character:SetPrimaryPartCFrame(game.Workspace.Elevator.TeleportPart.CFrame)
end

end)

I think I will report this to Roblox, thanks for all the support.