How do you use an ontouch function locally?

Hey. I was recently trying to make a checkpoint script locally, however an ontouch function doesn’t work for it. In a server script, the function is able to work, however not in a local script, which becomes quite annoying.

This is my script:

local debounces = { }
local Players = game:GetService("Players")
local part = script.Parent

script.Parent.Touched:Connect(function(part)
	local player = Players:GetPlayerFromCharacter(part.Parent)

	if debounces[player] then
		return
	end

	debounces[player] = true

	game:GetService("ReplicatedStorage"):WaitForChild("Client"):FireClient(player)

	local sound = script.Parent.LevelComplete:Clone()
    sound.Parent = player.PlayerGui
	sound:Play()

    script.Parent.Effect.Enabled = true
    wait(1)
    script.Parent.Effect.Enabled = false
end)

If you have any solutions, reply!
Thanks.

1 Like

Put a LocalScript in StarterCharacterScripts with the following code inside:

-- This is an example part. Set the first line to wherever your Part is located at
game:GetService("Workspace").Part.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
		-- Run your code here
	end
end)

The reason why your code isn’t firing the .Touched event is that LocalScripts only run when they are a descendant/child of the LocalPlayer, as in their GUI, starter scripts, etc.

3 Likes

Can you use it for multiple parts in a folder?
Each checkpoint I have is located in their own unique folder called ‘Checkpoints’, if you can show me how to make an ontouch function for them it’d be better then copy and pasting each part in the workspace. It’d also be good if the debounce would be included there for each one.

Yes you can.

local yourFolder = game:GetService("Workspace").Checkpoints:GetDescendants()
local debounce = false
local cooldown = 10 -- set this to whatever number you want the script to wait for

for _, v in pairs(yourFolder) do
	if v:IsA("BasePart") then
		v.Touched:Connect(function(hit)
			if hit.Parent:FindFirstChild("Humanoid") then
				if not debounce then
					debounce = true
					
					-- your code

					wait(cooldown)
					debounce = false
				end
			end
		end)
	end	
end

If you have any other questions let me know!

Code updated, it now will work as expected.

Will it be player-only because it’s a local script?

Code ran in LocalScripts that don’t fire remote events nor invoke remote functions will not affect other players, therefore, it will not set others’ spanwpoint.

Thanks, works so far, however there is 1 error. Is there a proper way to get the player from it and clone a sound from that checkpoint into the playergui?

Here is my current script:

local debounce = false
local Players = game:GetService("Players")

for _, v in pairs(workspace.Checkpoints:GetChildren()) do
	if v:IsA("SpawnLocation") then
		v.Touched:Connect(function(hit)
			local player = Players:GetPlayerFromCharacter(v.Parent)
			if hit.Parent:FindFirstChild("Humanoid") then
				if not debounce then
					debounce = true

					local sound = v.LevelComplete:Clone()
					sound.Parent = player.PlayerGui
					sound:Play()

					v.Effect.Enabled = true
					wait(1)
					v.Effect.Enabled = false
				end
			end
		end)
	end	
end

Your issue is here, you should be calling the GetPlayerFromCharacter() function with the hit.Parent argument.

Keep in mind that in this loop, v is your SpawnPoint part. Unless LevelComplete is a child of the SpawnPoint part, you will run into an error when trying to clone it.

Thanks for your help!
Only issue is that I need a debounce that lasts the entire server on each checkpoint touched. With the current script, when you touch ONE checkpoint it will set an ENTIRE debounce, not a debounce JUST for that checkpoint.

This is the checkpoint folder and its descendants:
image

That can be done with the following:

local Players = game:GetService("Players")

for _, v in pairs(workspace.Checkpoints:GetChildren()) do
	if v:IsA("SpawnLocation") then
		v.Touched:Connect(function(hit)
			local player = Players:GetPlayerFromCharacter(hit.Parent)
			if hit.Parent:FindFirstChild("Humanoid") then

				-- HIGHLIGHT
				v:FindFirstChild("TouchInterest"):Destroy()
				-- HIGHLIGHT
				
				local sound = v.LevelComplete:Clone()
				sound.Parent = player.PlayerGui
				sound:Play()

				v.Effect.Enabled = true
				wait(1)
				v.Effect.Enabled = false
			end
		end)
	end	
end
1 Like