How would you play a sound for a player that touches a checkpoint?

Hey, I’ve recently started working on an obby and I’d like to work on a checkpoint system similar to the Impossible Obby (or Ultimate Obby)

My issue is that I need to play a sound once when the player touches the checkpoint, but only the player should be able to hear it, not the entire playerbase.

I’ve checked as many topics as possible and haven’t found a proper script or anything helpful in topic replies.

Here is my code (everything works but the sound playing for the ontouch player):

local SoundService = game:GetService("SoundService")

local thing = script.Parent

local function confetti()
	for i, v in pairs(thing:GetDescendants()) do
		if v:IsA("ParticleEmitter") then
			v.Enabled = true
		end
	end
    wait(0.3)
	for i, v in pairs(thing:GetDescendants()) do
		if v:IsA("ParticleEmitter") then
			v.Enabled = false
		end
	end
end

thing.Touched:Connect(function(hit)
	local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
	if player then
      if workspace.sounds.LevelComplete.IsPlaying == false then
        workspace.sounds.LevelComplete:Play()
      end
        confetti()
	end
end)

Thanks!

1 Like

What you’re looking for is playing sounds locally. The Sound page has some documentation. You can create a Sound object locally and play it. This way only the client that calls the :Play() method on that sound will hear it. To hook this up to your checkpoint detection, you can use a RemoteEvent with the :FireClient() method which the client will (in a LocalScript) connect to the OnClientEvent and when fired, will play the locally created Sound.

1 Like

Would you mind making an in-depth script/guide about it? There’s a lot of replies like yours, however they only state what may happen but not actually how to do it.

Yeah! Will do. Give me like 30-minutes to an hour though so I can make a thorough tutorial that others will be able to use too.

change this into

local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
	if player then
    -- get a remote event and name it LevelCompleted
  game.ReplicatedStorage.LevelCompleted:FireClient(workspace.sounds.LevelComplete)

      end
-- local script
game.ReplicatedStorage.LevelCompleted.OnClientEvent:Connect(function(player,sound)
if workspace.sounds.LevelComplete.IsPlaying == false then
        workspace.sounds.LevelComplete:Play()
      end


end)
1 Like

Here’s just a small example. This showcases two sounds. The first, a global sound, is the piano music playing on a loop. It has a 3D position in the world meaning it will be quieter for players farther away. The second sound is a classic Victory sound. You can play this sound by clicking the screen gui button. The Victory sound is a local sound, meaning it will only be heard by one client. The reason these two sounds are global or local is because of where they exist in the game hierarchy. The piano sound is located in a Part which is replicated to all clients. The Victory sound on the other hand is located in a ScreenGui which is replicated to each client individually. This means that when a local script calls :Play() on the Victory sound, only that client will hear the sound.

LocalSoundExample.rbxl (31.3 KB)

Credit to:
EndorsedModel - for the Piano model
SirHatford - for the piano music
maximus_TV - for the Victory sound

1 Like

Hey, thanks for trying to help, however it doesn’t work and says this in the dev console:

spaghetti

Solutions?

:GetPlayerFromCharacter
That is the way to do it bro, an example would be:

local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
1 Like