Hello,
This code is gives a random amount of credits when the checkpoint is reached but it runs multiple times despite having a debounce if I touch the checkpoint it gives me about 1000 credits like there is a delay. Thanks for any help.
for _, part in cs:GetTagged("checkpoint") do
local soundPlayed = false
local creditsGiven = false
part.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
-- Creates a random coin amount
local randomCreditAmount = math.random(100, 250)
if soundPlayed == false then
soundPlayed = true
local soundClone = script.CheckpointSound:Clone()
soundClone.Parent = part
soundClone:Play()
-- Updates the players coin value
if creditsGiven == false then
creditsGiven = true
game.Players:GetPlayerFromCharacter(hit.Parent).leaderstats["Neon Credits"].Value += randomCreditAmount
print("Credits Given")
end
local cs = game:GetService("CollectionService")
local remoteEvent = game.ReplicatedStorage.FakeRespawnPlayer
local electricSound = script.ShockLoop
cs:GetInstanceAddedSignal("checkpoint"):Connect(function()
for _, part in cs:GetTagged("checkpoint") do
local soundPlayed = false
local creditsGiven = false
part.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
-- Creates a random coin amount
local randomCreditAmount = math.random(100, 250)
if soundPlayed == false then
soundPlayed = true
local soundClone = script.CheckpointSound:Clone()
soundClone.Parent = part
soundClone:Play()
-- Updates the players coin value
if creditsGiven == false then
creditsGiven = true
game.Players:GetPlayerFromCharacter(hit.Parent).leaderstats["Neon Credits"].Value += randomCreditAmount
print("Credits Given")
end
end
part.Color = Color3.new(0, 1, 0.333333)
-- Saves a vector3 value
game.Players:GetPlayerFromCharacter(hit.Parent):SetAttribute("CurrentCheckpoint", part.Position)
print("Checkpoint Saved")
end
end)
end
end)
cs:GetInstanceAddedSignal("resetBrick"):Connect(function()
for _, part in cs:GetTagged("resetBrick") do
part.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
print("Damage hit")
hit.Parent.HumanoidRootPart.Position = game.Players:GetPlayerFromCharacter(hit.Parent):GetAttribute("CurrentCheckpoint")
end
end)
local soundClone = electricSound:Clone()
soundClone.Parent = part
soundClone:Play()
print("Playing Sound")
end
end)
Sorry its a little messy but this script controls two things so the second cs function isn’t related to the problem
Though your debounces aren’t actually debounces, there’s nothing in your code that is allowing your checkpoints to deliver their rewards more than once to the first entity that touches them. Are you seeing a repeated output of “Credits Given”? If so, try replacing your print call with the following:
print(debug.traceback("Credits Given"))
This will help you understand more about where the print call is being made. Maybe you have multiple instances of the same programming running
Try to make soundPlayed and creditsGiven instances inside every checkpoint. The variables return to their value for each time it’s looped
local soundPlayed = Instance.new("BoolValue")
soundPlayed.Name = "soundPlayed"
soundPlayed.Value = false
soundPlayed.Parent = part
local creditsGiven = Instance.new("BoolValue")
creditsGiven.Name = "creditsGiven"
creditsGiven.Value = false
creditsGiven.Parent = part
Full Code
cs:GetInstanceAddedSignal("checkpoint"):Connect(function()
for _, part in cs:GetTagged("checkpoint") do
local soundPlayed = part:FindFirstChild("soundPlayed")
local creditsGiven = part:FindFirstChild("creditsGiven")
if not soundPlayed then
soundPlayed = Instance.new("BoolValue")
soundPlayed.Name = "soundPlayed"
soundPlayed.Value = false
soundPlayed.Parent = part
end
if not creditsGiven then
creditsGiven = Instance.new("BoolValue")
creditsGiven.Name = "creditsGiven"
creditsGiven.Value = false
creditsGiven.Parent = part
end
part.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
-- Creates a random coin amount
local randomCreditAmount = math.random(100, 250)
if soundPlayed.Value == false then
soundPlayed.Value = true
local soundClone = script.CheckpointSound:Clone()
soundClone.Parent = part
soundClone:Play()
-- Updates the players coin value
if creditsGiven.Value == false then
creditsGiven.Value = true
game.Players:GetPlayerFromCharacter(hit.Parent).leaderstats["Neon Credits"].Value += randomCreditAmount
print("Credits Given")
end
end
part.Color = Color3.new(0, 1, 0.333333)
-- Saves a vector3 value
game.Players:GetPlayerFromCharacter(hit.Parent):SetAttribute("CurrentCheckpoint", part.Position)
print("Checkpoint Saved")
end
end)
end
end)
By placing these variables within the event listener, their effect on the execution of the event listener becomes ephemeral; they’ll be reset the next time the event is invoked, essentially making them redundant. This would actually allow more than one player to claim the checkpoint multiple times
This is functionally equivalent to what OP has already. The variables created each iteration are not lost as they’re cached as upvalues in the event listener’s closure—each variable is unique to each event listener. You can see this in action with the following code:
local memories = {}
for number = 1, 3 do
local function memory()
print(number)
end
table.insert(memories, memory)
end
for _, memory in memories do
memory()
end
Never mind, I see your problem. Each time a new checkpoint is added, you’re iterating through all existing checkpoints and duplicating the existing event listeners. Your “debounces” were working, you just had multiple responses to the same collision with a single checkpoint.
cs:GetInstanceAddedSignal("checkpoint"):Connect(function()
for _, part in cs:GetTagged("checkpoint") do
Change your code to the following:
local function initializeCheckpoint(checkpoint)
-- The body of your "for _, part in cs:GetTagged("checkpoint") do" loop.
end
for _, checkpoint in cs:GetTagged("checkpooint") do
initializeCheckpoint(checkpoint)
end
cs:GetInstanceAddedSignal("checkpoint"):Connect(initializeCheckpoint)
This code separates the initialization of all existing checkpoints from the initialization of individual future checkpoints. Here is a fully revised version:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
local REWARD_MIN = 100
local REWARD_MAX = 250
local ShockLoopSound = script.ShockLoop
local function onLivingPlayerTouched(part: BasePart, callback: (player) -> ()): RBXScriptConnection
return part.Touched:Connect(function(otherPart: BasePart)
local character = otherPart.Parent
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid or humanoid.Health <= 0 then
return
end
local player = Players:GetPlayerFromCharacter(character)
if not player then
return
end
callback(player)
end)
end
local function initializeCheckpoint(checkpoint: BasePart)
local connection: RBXScriptConnection
connection = onLivingPlayerTouched(checkpoint, function(player: Player)
connection:Disconnect()
local leaderstats = player.leaderstats
local neonCredits = leaderstats["Neon Credits"]
neonCredits.Value += math.random(REWARD_MIN, REWARD_MAX)
checkpoint.Color = Color3.fromRGB(0, 255, 85)
end)
end
local function initializeResetBrick(resetBrick: BasePart)
local shockLoopSound = ShockLoopSound:Clone()
shockLoopSound.Parent = resetBrick
onLivingPlayerTouched(resetBrick, function(player: Player)
shockLoopSound:Play()
player.Character:PivotTo(CFrame.new(player:GetAttribute("CurrentCheckpoint")))
end)
end
local function initializeAll(tag: string, initializer: (BasePart) -> ())
for _, tagged in CollectionService:GetTagged(tag) do
initializer(tagged)
end
CollectionService:GetInstanceAddedSignal(tag):Connect(initializer)
end
initializeAll("Checkpoint", initializeCheckpoint)
initializeAll("ResetBrick", initializeResetBrick)
for _, part in cs:GetTagged("checkpoint") do
local rewarded = false
part.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") and not rewarded then
rewarded = true
local soundClone = script.CheckpointSound:Clone()
soundClone.Parent = part
soundClone:Play()
-- Creates a random coin amount
local randomCreditAmount = math.random(100, 250)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
player.leaderstats["Neon Credits"].Value += randomCreditAmount
print("Credits Given")
end
end)
end
if it doesn’t work, then you probably have multiple parts in the checkpoint being tagged or something
Well its a round based system so everytime the round is over all the tagged instances are destroyed and the map doesn’t exist until a player is loaded into the game so there are no initial checkpoints only generated checkpoints
That doesn’t matter. The fact that the checkpoints are loaded in triggers the event created with GetInstanceAddedSigal. This then leads to the problem I stated before, which is how you loop over all checkpoints that were loaded prior to those still loading and duplicate their event listeners. Try the solution I gave to you, or use my fully revised code. Do note that it does not exactly align with your current code, so some changes will need to be made
The only relevant difference between the revised code and your current code is that I used the proper naming convention for your tags (PascalCase). Did you make sure to update your tags to reflect this, or did you change my script to work with your current tags (camelCase)?