this keeps changing everyones leaderstat if 1 player hits the part, i want it to only happen to the specific player that hits the part.
local FinishDetector = workspace:WaitForChild("FinishThing"):WaitForChild("Detector")
local hasWon = false
FinishDetector.Touched:Connect(function(hit)
local character = hit.Parent
local player = game.Players:GetPlayerFromCharacter(character)
if player and not hasWon then
local checkpoint1 = CheckpointsFolder:FindFirstChild("1")
if checkpoint1 then
Wins.Value = Wins.Value + 1
player.leaderstats:FindFirstChild("🕹️Stage").Value = 1
hasWon = true
player.Character:SetPrimaryPartCFrame(checkpoint1.CFrame)
wait(5)
hasWon = false
myDataStore:SetAsync(player.UserId, {Stage = 1, Wins = Wins.Value, Deaths = Deaths.Value})
end
end
end)
Where exactly do you define Wins at? If it’s outside the .Touched event then that would be the issue since it isn’t exclusive to the player that touches the part.
Edit: Maybe i misunderstood what you needed. Is it the Stage or Wins that’s incrementing for everyone?
Try checking if the name of the character is equal to the name of the player. When you do “if player”, I think that is just checking to see if the player exists
local FinishDetector = workspace:WaitForChild("FinishThing"):WaitForChild("Detector")
local hasWon = false
FinishDetector.Touched:Connect(function(hit)
local character = hit.Parent
local player = game.Players:GetPlayerFromCharacter(character)
if character.Name == player.Name and not hasWon then
local checkpoint1 = CheckpointsFolder:FindFirstChild("1")
if checkpoint1 then
Wins.Value = Wins.Value + 1
player.leaderstats:FindFirstChild("🕹️Stage").Value = 1
hasWon = true
player.Character:SetPrimaryPartCFrame(checkpoint1.CFrame)
wait(5)
hasWon = false
myDataStore:SetAsync(player.UserId, {Stage = 1, Wins = Wins.Value, Deaths = Deaths.Value})
end
end
end)
server its the main handler, here is the full script.
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("MyDataStore")
local Rs = game.ReplicatedStorage
local Players = game:GetService("Players")
local Event = Rs:WaitForChild("Events")
local PS = game:GetService("PhysicsService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StartJumpingEvent = ReplicatedStorage.Events:WaitForChild("StartJumping")
local CollisionGroupName = "Players"
PS:RegisterCollisionGroup(CollisionGroupName)
PS:CollisionGroupSetCollidable(CollisionGroupName, CollisionGroupName, false)
Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(char)
local function ChangeGroup(Part)
if Part:IsA("BasePart") then
PS:SetPartCollisionGroup(Part, CollisionGroupName)
end
end
char.ChildAdded:Connect(ChangeGroup)
for _, Object in pairs(char:GetChildren()) do
ChangeGroup(Object)
end
end)
end)
game.Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder")
leaderstats.Parent = Player
leaderstats.Name = "leaderstats"
local Stage = Instance.new("NumberValue")
Stage.Parent = leaderstats
Stage.Name = "🕹️Stage"
Stage.Value = 1 -- Start at stage 1
local Wins = Instance.new("NumberValue")
Wins.Parent = leaderstats
Wins.Name = "🏆Wins"
Wins.Value = 0
local Deaths = Instance.new("NumberValue")
Deaths.Parent = leaderstats
Deaths.Name = "💀Deaths"
Deaths.Value = 0
local CheckpointsFolder = game.Workspace:WaitForChild("Checkpoints")
local debounce = false -- Declare debounce variable here
for i, Checkpoint in pairs(CheckpointsFolder:GetChildren()) do
Checkpoint.Touched:Connect(function(Hit)
if Hit.Parent:FindFirstChild("Humanoid") then
local PlayerHit = game.Players:GetPlayerFromCharacter(Hit.Parent)
Checkpoint.BrickColor = BrickColor.new("Bright red")
if PlayerHit.leaderstats:FindFirstChild("🕹️Stage").Value == tonumber(Checkpoint.Name) - 1 then
PlayerHit.leaderstats:FindFirstChild("🕹️Stage").Value = Checkpoint.Name
workspace.SoundFx.Success:Play()
Event.CheckPointEvent:FireClient(Player)
myDataStore:SetAsync(Player.UserId, {Stage = Stage.Value, Wins = Wins.Value, Deaths = Deaths.Value})
end
end
end)
end
local FinishDetector = workspace:WaitForChild("FinishThing"):WaitForChild("Detector")
local hasWon = false
FinishDetector.Touched:Connect(function(hit)
local character = hit.Parent
local player = game.Players:GetPlayerFromCharacter(character)
if character.Name == player.Name and not hasWon then
local checkpoint1 = CheckpointsFolder:FindFirstChild("1")
if checkpoint1 then
Wins.Value = Wins.Value + 1
player.leaderstats:FindFirstChild("🕹️Stage").Value = 1
hasWon = true
player.Character:SetPrimaryPartCFrame(checkpoint1.CFrame)
wait(5)
hasWon = false
myDataStore:SetAsync(player.UserId, {Stage = 1, Wins = Wins.Value, Deaths = Deaths.Value})
end
end
end)
Player.CharacterAdded:Connect(function(Character)
repeat
wait()
until Character:FindFirstChild("HumanoidRootPart")
local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
HumanoidRootPart.CFrame = CheckpointsFolder:FindFirstChild(tostring(Stage.Value)).CFrame + Vector3.new(0, 2, 0)
-- Detect when the player's character dies
Character:WaitForChild("Humanoid").Died:Connect(function()
Deaths.Value = Deaths.Value + 1
-- Save the updated value to the datastore
myDataStore:SetAsync(Player.UserId, {Stage = Stage.Value, Wins = Wins.Value, Deaths = Deaths.Value})
end)
end)
local data = myDataStore:GetAsync(Player.UserId)
if data then
Stage.Value = data.Stage
Wins.Value = data.Wins
Deaths.Value = data.Deaths
end
end)
StartJumpingEvent.OnServerEvent:Connect(function(player)
StartJumpingEvent:FireClient(player)
end)
local music = game.Workspace.SoundFx["Cartoony A"]
music.Looped = true
music.Parent = workspace
music:Play()
I see your issue. I believe this is caused by connecting the .Touched event in a .PlayerAdded event, meaning there is one .Touched event per player that joins. This can result in the values incrementing for everyone, as well as wasting resources since you have a bunch of connections for no reason. Move the .Touched connections outside the .PlayerAdded connection and let me know if that fixes!
I attempted to fix it for you, this should work, but if it doesn’t just let me know. I also changed out the HasWon boolean in favor of an attribute. This just makes it easier to keep track of which boolean belongs to which player without mapping it out.
Edit: For performance reasons, please cache the result of FindFirstChild whenever you can.
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("MyDataStore")
local Rs = game.ReplicatedStorage
local Players = game:GetService("Players")
local Event = Rs:WaitForChild("Events")
local PS = game:GetService("PhysicsService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StartJumpingEvent = ReplicatedStorage.Events:WaitForChild("StartJumping")
local CollisionGroupName = "Players"
PS:RegisterCollisionGroup(CollisionGroupName)
PS:CollisionGroupSetCollidable(CollisionGroupName, CollisionGroupName, false)
Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(char)
local function ChangeGroup(Part)
if Part:IsA("BasePart") then
PS:SetPartCollisionGroup(Part, CollisionGroupName)
end
end
char.ChildAdded:Connect(ChangeGroup)
for _, Object in pairs(char:GetChildren()) do
ChangeGroup(Object)
end
end)
end)
game.Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder")
leaderstats.Parent = Player
leaderstats.Name = "leaderstats"
local Stage = Instance.new("NumberValue")
Stage.Parent = leaderstats
Stage.Name = "🕹️Stage"
Stage.Value = 1 -- Start at stage 1
local Wins = Instance.new("NumberValue")
Wins.Parent = leaderstats
Wins.Name = "🏆Wins"
Wins.Value = 0
local Deaths = Instance.new("NumberValue")
Deaths.Parent = leaderstats
Deaths.Name = "💀Deaths"
Deaths.Value = 0
Player.CharacterAdded:Connect(function(Character)
repeat
wait()
until Character:FindFirstChild("HumanoidRootPart")
local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
HumanoidRootPart.CFrame = workspace:WaitForChild("Checkpoints"):FindFirstChild(tostring(Stage.Value)).CFrame + Vector3.new(0, 2, 0)
-- Detect when the player's character dies
Character:WaitForChild("Humanoid").Died:Connect(function()
Deaths.Value = Deaths.Value + 1
-- Save the updated value to the datastore
myDataStore:SetAsync(Player.UserId, {Stage = Stage.Value, Wins = Wins.Value, Deaths = Deaths.Value})
end)
end)
local data = myDataStore:GetAsync(Player.UserId)
if data then
Stage.Value = data.Stage
Wins.Value = data.Wins
Deaths.Value = data.Deaths
end
end)
StartJumpingEvent.OnServerEvent:Connect(function(player)
StartJumpingEvent:FireClient(player)
end)
for i, Checkpoint in pairs(workspace:WaitForChild("Checkpoints"):GetChildren()) do
Checkpoint.Touched:Connect(function(Hit)
if Hit.Parent:FindFirstChild("Humanoid") then
local PlayerHit = game.Players:GetPlayerFromCharacter(Hit.Parent)
Checkpoint.BrickColor = BrickColor.new("Bright red")
local stage = PlayerHit.leaderstats:FindFirstChild("🕹️Stage")
if stage.Value == tonumber(Checkpoint.Name) - 1 then
stage.Value = Checkpoint.Name
workspace.SoundFx.Success:Play()
Event.CheckPointEvent:FireClient(PlayerHit)
myDataStore:SetAsync(PlayerHit.UserId, {
stage.Value,
Wins = PlayerHit.leaderstats:FindFirstChild("🏆Wins").Value,
Deaths = PlayerHit.leaderstats:FindFirstChild("💀Deaths").Value
})
end
end
end)
end
local FinishDetector = workspace:WaitForChild("FinishThing"):WaitForChild("Detector")
FinishDetector.Touched:Connect(function(hit)
local character = hit.Parent
local player = game.Players:GetPlayerFromCharacter(character)
if character.Name == player.Name and not player:GetAttribute("HasWon") then
local checkpoint1 = workspace:WaitForChild("Checkpoints"):FindFirstChild("1")
if checkpoint1 then
local wins = player.leaderstats:FindFirstChild("🏆Wins")
wins.Value += 1
player.leaderstats:FindFirstChild("🕹️Stage").Value = 1
player:SetAttribute("HasWon", true)
player.Character:SetPrimaryPartCFrame(checkpoint1.CFrame)
task.wait(5)
player:SetAttribute("HasWon", false)
myDataStore:SetAsync(player.UserId, {
Stage = 1,
Wins = wins.Value,
Deaths = player.leaderstats:FindFirstChild("💀Deaths").Value
})
end
end
end)
local music = game.Workspace.SoundFx["Cartoony A"]
music.Looped = true
music.Parent = workspace
music:Play()