How to add sound to an obby checkpoint

Hello! So today I have come back to a obby project I started working on about a year ago, and was having a look at my game. When I tested walking over the checkpoint there was no sound effects playing. In the script, I know how to add sound effects but I dont know where to put the line of code, as I havent looked at this script for a while.

Here is the code:

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local ObbyDataStore = DataStoreService:GetDataStore("ObbyDataStore")
local MarketPlaceService = game:GetService("MarketplaceService")
local ReplicatedService = game:GetService("ReplicatedStorage")
local SkipStage = ReplicatedService:WaitForChild("SkipStage")
local ResetStage = ReplicatedService:WaitForChild("ResetStage")

local Checkpoints = workspace:WaitForChild("Checkpoints")
local inGameStartupPlayers = {}
local CurrentStage = {}
local TouchDb = {}

local ProductId = 1182478594

local function NewCharacter(player, char)
	local TempCurrentStage  = CurrentStage[player.UserId]
	if TempCurrentStage ~= nil then
		local TempCheckpoint = Checkpoints:FindFirstChild(TempCurrentStage)
		if TempCheckpoint ~= nil then
			repeat wait(0.1) until char.PrimaryPart ~= nil
			char:SetPrimaryPartCFrame(CFrame.new(TempCheckpoint.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(TempCheckpoint.Orientation.Y) + math.rad(90), 0))
		end
	end
end

local function NewPlayer(player)
	local success, stage = pcall(function()
		return (ObbyDataStore:GetAsync(player.UserId)) or 1
	end)
	CurrentStage[player.UserId] = stage
	
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	local Stages = Instance.new("IntValue", leaderstats)
	Stages.Name = "Stage"
	Stages.Value = stage
	
	local TempChar = player.character
	if TempChar ~= nil then
		NewCharacter(player, TempChar)
	end
	player.CharacterAdded:Connect(function(char)
		NewCharacter(player, char)
	end)
end

Players.PlayerAdded:Connect(function(player)
	if inGameStartupPlayers[player] == nil then
		NewPlayer(player)
	end
end)

Players.PlayerRemoving:Connect(function(player)
	local success = pcall(function()
		ObbyDataStore:SetAsync(player.UserId, CurrentStage[player.UserId])
	end)
	CurrentStage[player.UserId] = nil
end)

ResetStage.OnServerEvent:Connect(function(player)
	CurrentStage[player.UserId] = 1
	local TempLeaderstats = player:FindFirstChild("leaderstats")
	if TempLeaderstats ~= nil then
		local TempStage = TempLeaderstats:FindFirstChild("Stage")
		if TempStage ~= nil then
			TempStage.Value = 1
			end
	end
	NewCharacter(player, player.Character)
end)

SkipStage.OnServerInvoke = function(player)
	local connection
	local leaderstats = player:FindFirstChild("leaderstats")
	if leaderstats ~= nil then
		local Stage2 = leaderstats:FindFirstChild("Stage")
		if Stage2 ~= nil then
			if #Checkpoints:GetChildren() ~= Stage2.Value then
				local PurchaseResult = "Purchase Failed"
				connection = MarketPlaceService.PromptProductPurchaseFinished:Connect(function(userId, productId, purchased)
					if player.UserId == userId and productId == ProductId then
						if purchased == true then
							PurchaseResult = "Success"
						end
					end
					connection:Disconnect()
				end)
				MarketPlaceService:PromptProductPurchase(player, ProductId)
				repeat wait(0.1) until connection.Connected == false or Players:GetPlayerByUserId(player.UserId) == nil
				return PurchaseResult
			else
				return "You have reached the highest stage!"
			end
		end
	end
end

MarketPlaceService.ProcessReceipt = function(recieptInfo) 
	if recieptInfo.ProductId == ProductId then
		local player = Players:GetPlayerByUserId(recieptInfo.PlayerId)
		if player ~= nil then
			CurrentStage[player.UserId] = CurrentStage[player.UserId] + 1
			local leaderstats = player:FindFirstChild("leaderstats")
			if leaderstats ~= nil then
				local Stage = leaderstats:FindFirstChild("Stage")
				if Stage ~= nil then
					Stage.Value = CurrentStage[player.UserId]
				end
			end
			local  TempChar = player.Character
			if TempChar ~= nil then
				NewCharacter(player, TempChar)
			end
			return Enum.ProductPurchaseDecision.PurchaseGranted
		end
	end
	return Enum.ProductPurchaseDecision.NotProcessedYet
end

for i,v in pairs(Checkpoints:GetChildren()) do
	local StageNum = tonumber(v.Name)
	v.Touched:Connect(function(hit)
		local char = hit.Parent
		if char ~= nil then
			local Humanoid = char:FindFirstChildOfClass("Humanoid")
			if Humanoid ~= nil and Humanoid.Health > 0 then
				local player = Players:GetPlayerFromCharacter(char)
				if player ~= nil and (TouchDb[player.UserId] or 0) + 1 <= os.time() then
					TouchDb[player.UserId] = os.time()
					local TempCurrentStage = CurrentStage[player.UserId]
					if TempCurrentStage == StageNum - 1 then
						CurrentStage[player.UserId] = StageNum
						local TempLeaderstats = player:FindFirstChild("leaderstats")
						if TempLeaderstats ~= nil then
							local TempStage = TempLeaderstats:FindFirstChild("Stage")
							if TempStage ~= nil then
								TempStage.Value = StageNum
							end
						end
					end
				end
			end
		end
	end)
end

inGameStartupPlayers = Players:GetPlayers()
for i,v in pairs(inGameStartupPlayers) do
	spawn(function()
		NewPlayer(v)
	end)
end

game:BindToClose(function()
	for i,v in pairs(Players:GetPlayers()) do
		ObbyDataStore:SetAsync(v.UserId, CurrentStage[v.UserId])
	end
	wait(1)
end)

inGameStartupPlayers = {}

All I need to know is where to put the thing to play the sound effect in the script. ty :smiley:

2 Likes

What you would do
(implement this in localscript if wanted play sound locally)

everytime TempStage value increases, play the sound (using GetPropertyChangedSignal(“value”)

1 Like

uhh im kinda new to scripting… could you explain in a bit more detail :smiley:

1 Like

In a localscript do the following:

TempStage -- Define yourself, it's the value you change everytime they get to a new checkpoint

TempStage:GetPropertyChangedSignal("Value"):Connect(function()
--PlaySound here
end)

If you want it to play for all players nearby, instead place a sound-object inside the checkpoint, and play that, when you change the TempStage.Value in your script.

1 Like

where would i create the local script or does it not matter

1 Like

In StarterGUI. If you already got a localscript in there, just insert the code above in that, instead of creating a seperate script for this single function.

1 Like
local TempLeaderstats = player:FindFirstChild("leaderstats")
if TempLeaderstats ~= nil then
	local TempStage = TempLeaderstats:FindFirstChild("Stage") -- Define yourself, it's the value you change everytime they get to a new checkpoint

	TempStage:GetPropertyChangedSignal("Value"):Connect(function()
		script["Ding Ding!"]:Play()
end)

there are no errors but it just doesnt play the sound do you know why?

1 Like

You need to wait for it to exist.

local TempLeaderstats = player:WaitForChild("leaderstats")

local TempStage = TempLeaderstats:FindFirstChild("Stage") -- Define yourself, it's the value you change everytime they get to a new checkpoint

TempStage:GetPropertyChangedSignal("Value"):Connect(function()
	script["Ding Ding!"]:Play()
end)
1 Like

Players.Player1.PlayerGui.LocalScript:1: attempt to index nil with 'WaitForChild'

1 Like

That means player is nil, thought you would define it yourself but anyways your new to scripting.

local player = game.Players.LocalPlayer

local TempLeaderstats = player:WaitForChild("leaderstats")

local TempStage = TempLeaderstats:FindFirstChild("Stage") -- Define yourself, it's the value you change everytime they get to a new checkpoint

TempStage:GetPropertyChangedSignal("Value"):Connect(function()
	script["Ding Ding!"]:Play()
end)
1 Like

ty it worked but idk is it possible for when tempstage gets changed the brick you step on spins around like 720 degrees?

1 Like
local player = game.Players.LocalPlayer

local TempLeaderstats = player:WaitForChild("leaderstats")

local TempStage = TempLeaderstats:FindFirstChild("Stage") -- Define yourself, it's the value you change everytime they get to a new checkpoint

TempStage:GetPropertyChangedSignal("Value"):Connect(function()
	script["Ding Ding!"]:Play()

	local character = player.Character

	if character and character:FindFirstChild('HumanoidRootPart') then
		local pos = character.HumanoidRootPart.Position

		for i = 0, 720 do
			character.HumanoidRootPart.CFrame = CFrame.new(pos) * CFrame.Angles(0,i,0) -- dont know if this would work, would prob have to change one of the zeroes to 90 or something

			task.wait()
		end
	end
end)
1 Like

hmmm, idk if u consider my character endlessly spinning working…

1 Like

and what i mean by spin is like the part spinning not the character

1 Like

Oh, you mean the part. Then you would have to change the original script.

1 Like