Need help with adding checkpoint effects to my obby!

Yo, anybody mind telling me how I can add little confetti/sparkle effects to my checkpoints when a player walks over em? I already have a local checkpoint noise, but I wanted to add a local effect since I think it would look nice when completing a stage. I’ll post both my checkpoint script in serverscriptservice and my local checkpoint sounds script down below!

Main checkpoint script in ServerScriptService:

local checkpoints = workspace:WaitForChild("Checkpoints")

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local DatastoreService = game:GetService("DataStoreService")
local Data = DatastoreService:GetDataStore("1")
local sessionData = {}

function PlayerAdded(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"

	local stage = Instance.new("NumberValue")
	stage.Name = "Stage"
	stage.Parent = leaderstats

	local success = nil
	local playerData = nil
	local attempt = 1

	repeat 
		success, playerData = pcall(function() -- here pcall or protected call is just repeat waiting until the data loads for the player
			return Data:GetAsync(player.UserId)
		end)

		attempt += 1
		if not success then 
			warn(playerData)
			task.wait(2)
		end

	until success or attempt == 5 -- it repeats it until it loads

	if success then --if it loads then make the table with their data inside
		print("Data loaded: "..player.Name)
		if not playerData then -- if they have no table then they're a new player so we create the table 
			print("new player, giving default data")

			playerData = {
				["Stage"] = 1, --add all your values and stuff inside of the data

			}
		end

		sessionData[player.UserId] = playerData --set the data to a table with the players id and make to make a variable
	else
		warn("couldnt load data: "..player.Name)
		player:Kick("couldnt load your data, rejoin") --if the data couldnt load we kick them so their not just sitting there forever waiting
	end

	stage.Value = sessionData[player.UserId].Stage --here we get the numbervalue created above and get the value of it and set it to the value inside of the table

	stage:GetPropertyChangedSignal("Value"):Connect(function()
		sessionData[player.UserId].Stage = stage.Value --update the table value whenever the leaderstat value changes
	end)


	leaderstats.Parent = player

end

Players.PlayerAdded:Connect(function(player)
	PlayerAdded(player)

	player.CharacterAdded:Connect(function(char)
		local leaderstats = player:WaitForChild("leaderstats")
		local stage = leaderstats.Stage

		local hum = char:WaitForChild("Humanoid")
		task.wait()
		char:MoveTo(checkpoints[stage.Value].Position)

		hum.Touched:Connect(function(hit)
			if hit.Parent == checkpoints then
				if tonumber(hit.Name) == stage.Value + 1 then
					stage.Value += 1
				end
			end
		end)
	end)
end)



function PlayerLeaving(player)

	if sessionData[player.UserId] then
		local success = nil
		local errorMsg = nil
		local attempt = 1


		repeat
			success, errorMsg = pcall(function()
				Data:SetAsync(player.UserId, sessionData[player.UserId]) --here is the same as loading data just repeat waits until the data saves
			end)

			attempt += 1
			if not success then 
				warn(errorMsg)
				task.wait(2)
			end

		until success or attempt == 5

		if success then 
			print("Data saved: "..player.Name)
		else
			warn("Cant save: "..player.Name)
		end

	end

end

Players.PlayerRemoving:Connect(PlayerLeaving)

function ServerShutdown()
	if RunService:IsStudio() then
		return
	end

	for i, player in ipairs(Players:GetPlayers()) do
		task.spawn(function()
			PlayerLeaving(player)
		end)
	end
end
game:BindToClose(ServerShutdown)

Checkpoint sounds local script in StarterPlayerScripts:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player = game.Players.LocalPlayer

player:WaitForChild("leaderstats")

local CheckpointsFolder = workspace:WaitForChild("Checkpoints")

local function updateCheckpointColors()
	
	for _, part in ipairs(CheckpointsFolder:GetDescendants()) do
		if part:IsA("BasePart") and part.Parent == CheckpointsFolder then
			local stageNumber = tonumber(part.Name)
			if stageNumber and game.Players.LocalPlayer.leaderstats.Stage.Value >= stageNumber then
				part.BrickColor = BrickColor.new("Light reddish violet")
			end
		end
	end
	
	if ReplicatedStorage:FindFirstChild("CheckpointSound") then
		ReplicatedStorage.CheckpointSound:Play()
	end
	
end

updateCheckpointColors()

player.leaderstats.Stage.Changed:Connect(updateCheckpointColors)

You can create a particle emitter and parent it to your current checkpoint.

Code:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player = game.Players.LocalPlayer
local stage = player:WaitForChild("leaderstats"):WaitForChild("Stage")
local CheckpointsFolder = workspace:WaitForChild("Checkpoints")

local particleEmitter = Instance.new("ParticleEmitter")
particleEmitter.Enabled = false

local function updateCheckpointColors(playerStage)
	for _, part in ipairs(CheckpointsFolder:GetChildren()) do
		if part:IsA("BasePart") then
			local stageNumber = tonumber(part.Name)
			
			if stageNumber and playerStage >= stageNumber then
				part.BrickColor = BrickColor.new("Light reddish violet")
			end
		end
	end

	if ReplicatedStorage:FindFirstChild("CheckpointSound") then
		ReplicatedStorage.CheckpointSound:Play()
	end
	
	local currentStage = CheckpointsFolder[playerStage]
	particleEmitter.Parent = currentStage
	particleEmitter:Emit(20)
end

stage.Changed:Connect(updateCheckpointColors)
updateCheckpointColors(stage.Value)
2 Likes

I’ll try that out right now, gimme one second. :sunglasses:

By the way, instead of doing:

for _, part in ipairs(CheckpointsFolder:GetDescendants()) do
	if  part.Parent == CheckpointsFolder then
		-- Code
	end
end

You can do:

for _, part in ipairs(CheckpointsFolder:GetChildren()) do
	-- Code
end

Which would be more performant and readable.

Wait, so when I put particleEmitter.Enabled = True where do I go to add a certain effect? Im new to this stuff so I’m worried about messing things up :rofl:

No, you need to use :Emit unless you want to deal with disabling the ParticleEmitter after. Just take a look at my code.

Is this what you meant for more performant and readable? I just wanna know if I did it right

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player = game.Players.LocalPlayer

player:WaitForChild("leaderstats")

local CheckpointsFolder = workspace:WaitForChild("Checkpoints")

local function updateCheckpointColors()
	
	for _, part in ipairs(CheckpointsFolder:GetChildren()) do
		local stageNumber = tonumber(part.Name)
		if stageNumber and game.Players.LocalPlayer.leaderstats.Stage.Value >= stageNumber then
			part.BrickColor = BrickColor.new("Light reddish violet")
	end
	
		if ReplicatedStorage:FindFirstChild("CheckpointSound") then
			end
		end
		ReplicatedStorage.CheckpointSound:Play()
	end
	


updateCheckpointColors()

player.leaderstats.Stage.Changed:Connect(updateCheckpointColors)

Take a look at my code, it has everything I have told you to add.

Alright I changed it up some, only error it says now is "unknown global ‘stage’

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player = game.Players.LocalPlayer

player:WaitForChild("leaderstats")

local CheckpointsFolder = workspace:WaitForChild("Checkpoints")

local particleEmitter = Instance.new("ParticleEmitter")
particleEmitter.Enabled = false


local function updateCheckpointColors()
	
	for _, part in ipairs(CheckpointsFolder:GetChildren()) do
		local stageNumber = tonumber(part.Name)
		if stageNumber and game.Players.LocalPlayer.leaderstats.Stage.Value >= stageNumber then
			part.BrickColor = BrickColor.new("Light reddish violet")
	end
	
		if ReplicatedStorage:FindFirstChild("CheckpointSound") then
			end
		end
		ReplicatedStorage.CheckpointSound:Play()
	end

local currentStage = CheckpointsFolder[stage]
particleEmitter.Parent = currentStage
particleEmitter:Emit(20)



updateCheckpointColors()

player.leaderstats.Stage.Changed:Connect(updateCheckpointColors)

Please just use my code and tinker after. You didn’t take in the value in the function like my code does.

My bad I was cooking so I just saw this and changed it to your code, now what do I do? Did you want me to remove if part:IsA("BasePart") then local stageNumber = tonumber(part.Name) and put the rest of the code there? Or do I just leave it like it is? Also, I’m fairly new to all this scripting stuff and I appreciate you being patient with me gang. :sunglasses: :100:

2 Likes

It should work as is.

These errors right here popped up. I didn’t touch anything in your code!


Line 25:

local currentStage = CheckpointsFolder[stage]

Line 31:

updateCheckpointColors(stage.Value)

Oops, I made a typo, check my edited code.

1 Like

All good mane and it works! Preciate the help, but one more thing. Do you know how I could change it to rainbow confetti or something?

1 Like

Change the properties of the ParticleEmitter.

Code:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player = game.Players.LocalPlayer
local stage = player:WaitForChild("leaderstats"):WaitForChild("Stage")
local CheckpointsFolder = workspace:WaitForChild("Checkpoints")

local particleEmitter = Instance.new("ParticleEmitter")
particleEmitter.Enabled = false
particleEmitter.Color = ColorSequence.new({
	ColorSequenceKeypoint.new(0, Color3.fromRGB(255, 0, 0)),
	ColorSequenceKeypoint.new(0.25, Color3.fromRGB(255, 238, 0)),
	ColorSequenceKeypoint.new(0.5, Color3.fromRGB(0, 255, 8)),
	ColorSequenceKeypoint.new(0.75, Color3.fromRGB(0, 136, 255)),
	ColorSequenceKeypoint.new(1, Color3.fromRGB(157, 0, 255)),
})

local function updateCheckpointColors(playerStage)
	for _, part in ipairs(CheckpointsFolder:GetChildren()) do
		if part:IsA("BasePart") then
			local stageNumber = tonumber(part.Name)

			if stageNumber and playerStage >= stageNumber then
				part.BrickColor = BrickColor.new("Light reddish violet")
			end
		end
	end

	if ReplicatedStorage:FindFirstChild("CheckpointSound") then
		ReplicatedStorage.CheckpointSound:Play()
	end

	local currentStage = CheckpointsFolder[playerStage]
	particleEmitter.Parent = currentStage
	particleEmitter:Emit(20)
end

stage.Changed:Connect(updateCheckpointColors)
updateCheckpointColors(stage.Value)
2 Likes

Preciate all the help mane have a good one! :sunglasses: :100:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.