How can you play a sound only once on a touched event?

Everytime I touch the checkpoint it spams the sound effect. I would like to know if a scripter can help! thank you for your time!

for _, checkpoint in pairs(game.Workspace.Checkpoints:GetChildren()) do
	checkpoint.Touched:Connect(function(hit)
		if hit.Parent:FindFirstChild("Humanoid") then
			checkpoint.BrickColor = BrickColor.new("Lime green")
			game.SoundService.CheckpointSound:Play()
			
			local player = game.Players:GetPlayerFromCharacter(hit.Parent)
			
			local checkpointNumber = tonumber(checkpoint.Name)
			
			if player.leaderstats.Stage.Value < checkpointNumber then
				player.leaderstats.Stage.Value = checkpointNumber
			end
		end
	end)
end
1 Like

Touching the checkpoint makes every checkpoints green ?

1 Like

yes it is red and then when touched turns green

1 Like

It changes the color of only one checkpoint ?

I do want all the checkpoints to be green from past checkpoints and yes it turns green when the checkpoint is touched and turns only 1

local PlayerService = game:GetService("Players")
local SoundService = game:GetService("SoundService")

local Checkpoints = workspace:WaitForChild("Checkpoints", 30)
local CheckSound = SoundService:WaitForChild("CheckpointSound", 30)

local SoundTable = {}

for i, Child in pairs(Checkpoints:GetChildren()) do
	SoundTable[Child] = false
	
	Child.Touched:Connect(function(Hit)
		local Player = PlayerService:GetPlayerFromCharacter(Hit.Parent)
		local Humanoid = Hit.Parent:FindFirstChildWhichIsA("Humanoid")
		
		if Player and Humanoid then
			local leaderstats = Player and Player:FindFirstChild("leaderstats")
			local Stage = leaderstats and leaderstats:FindFirstChild("Stage")			
			local Number = tonumber(Child.Name)
			
			if SoundTable[Child] == false then
				Child.BrickColor = BrickColor.new("Lime green")
				CheckSound:Play()
				SoundTable[Child] = true 
			end
			
			if Stage and Stage.Value < Number then
				Stage.Value = Number
			end
		end
	end)
end

didnt work, want me to show you the full script?

My bad, i forgot to add SoundTable[Child] = true retry it ^^

It spams the sound because the .Touched event will fire multiple times, adding a debounce may fix your problem.

thx so much! Do you know how the green color can still stay after joining and leaving the game? here’s the full script!

local dataStoreService = game:GetService("DataStoreService")
local stageStore = dataStoreService:GetDataStore("PlayerStageDataStore")

function plrToStage(plr)
	repeat wait() until plr.Character.HumanoidRootPart
	
	local stagePart = game.Workspace.Checkpoints:FindFirstChild(tostring(plr.leaderstats.Stage.Value))
	
	plr.Character.HumanoidRootPart.CFrame = stagePart.CFrame + Vector3.new(0,2.5,0)
end

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local stage = Instance.new("IntValue")
	stage.Name = "Stage"
	stage.Parent = leaderstats
	
	local success, errorMsg = pcall(function()
		stage.Value = stageStore:GetAsync(player.UserId)
	end)
	
	if success then
		print("Successfully got "..player.Name.."'s stage data.")
	else
		warn(errorMsg)
	end
	if player.Character then
		plrToStage(player)
	end
	player.CharacterAdded:Connect(function()
		plrToStage(player)
	end)
end)

game.Players.PlayerRemoving:Connect(function(player)
	local success, errorMsg = pcall(function()
		stageStore:SetAsync(player.UserId,player.leaderstats.Stage.Value)
	end)
	
	if success then
		print("Successfully saved"..player.Name.."'s stage data.")
	else
		warn(errorMsg)
	end
end)

local PlayerService = game:GetService("Players")
local SoundService = game:GetService("SoundService")

local Checkpoints = workspace:WaitForChild("Checkpoints", 30)
local CheckSound = SoundService:WaitForChild("CheckpointSound", 30)

local SoundTable = {}

for i, Child in pairs(Checkpoints:GetChildren()) do
	SoundTable[Child] = false

	Child.Touched:Connect(function(Hit)
		local Player = PlayerService:GetPlayerFromCharacter(Hit.Parent)
		local Humanoid = Hit.Parent:FindFirstChildWhichIsA("Humanoid")

		if Player and Humanoid then
			local leaderstats = Player and Player:FindFirstChild("leaderstats")
			local Stage = leaderstats and leaderstats:FindFirstChild("Stage")			
			local Number = tonumber(Child.Name)

			if SoundTable[Child] == false then
				Child.BrickColor = BrickColor.new("Lime green")
				CheckSound:Play()
				SoundTable[Child] = true
			end

			if Stage and Stage.Value < Number then
				Stage.Value = Number
			end
		end
	end)
end

Theres a folder called Checkpoints with 0,1,2,3,etc

sorry i didnt fully read the question

You’re asking to me or PokeDB ? because you pinged him but you used my code xD

You im sorry lol the avatars looked similar

Alright, so yeah there is a way to keep the checkpoint green color even by leaving / rejoining the game, but the thing is that it is a Server Script, so all players are going to see it, which mean if a player is at checkpoint 2, it will be green, if another player is at checkpoint 3, it also is going to be green… is it what you’re looking for ?

It is also same for the sounds, each time someone reach a chekpoint, all other players are going to ear it too

So I need to put it to a local script? I also need to have all recent checkpoints from that player to be green and saved

Yeah, you can do the value save into the server script, and the effects into a local script… i’m going to help you, just let me some minutes ^^

Ok! I never use local scripts so I have no idea :sob: Thank you so much for helping me out with this.

No problem, could you try this into a local script in “StarterCharacterScript” ?
It should put all reached spawnpoints to green when joined the game, and also play the sound as well as puting all new reached spawnpoints to green only once

local PlayerService = game:GetService("Players")
local SoundService = game:GetService("SoundService")

local Player = PlayerService.LocalPlayer
local Character = script.Parent

local Checkpoints = workspace:WaitForChild("Checkpoints", 30)
local CheckSound = SoundService:WaitForChild("CheckpointSound", 30)

local leaderstats = Player and Player:WaitForChild("leaderstats", 30)
local Stage = leaderstats and leaderstats:WaitForChild("Stage", 30)

local Connections = {}

for i, Child in pairs(Checkpoints:GetChildren()) do
	if tonumber(Child.Name) <= Stage.Value then
		Child.BrickColor = BrickColor.new("Lime green")
	else
		Connections[Child] = Child.Touched:Connect(function(Hit)
			local NewPlayer = PlayerService:GetPlayerFromCharacter(Hit.Parent)
			local Humanoid = Hit.Parent:FindFirstChildWhichIsA("Humanoid")

			if NewPlayer and Humanoid and NewPlayer == Player and Humanoid.Parent == Character then		
				Child.BrickColor = BrickColor.new("Lime green")
				CheckSound:Play()
				Connections[Child]:Disconnect()
			end
		end)
	end
end

what do I do with the script? what would be removed?