Hello! Im trying to make a leaderstat, when you touch an object it goes up by +1
Here is my code:
pumpkins = game.Workspace.Pumpkins
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local timeingame = Instance.new("IntValue")
timeingame.Name = "Pumpkins"
timeingame.Parent = leaderstats
while true do
function KillOnTouch(Part)
local Victim = pumpkins:FindFirstChildWhichIsA("Humanoid") -- Detects a player and identifies them as a Variable.
if Victim ~= nil then -- Finds out if the part that touches it is a Player.
player.leaderstats.Time.Value = player.leaderstats.Time.Value + 1
end
end
end
end)
script.Parent.Touched:Connect(KillOnTouch) -- Calls the function to occur when something touches the Part.
-----------------------------------------------| Save Stats |------------------------------------------------------------
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("myDataStore")
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Time = Instance.new("IntValue")
Time.Name = "Pumpkins"
Time.Parent = leaderstats
local playerUserId = "Player"..player.UserId
local data
local success, errormessage = pcall(function()
data = myDataStore:GetAsync(playerUserId)
end)
if success then
Time.Value = data
end
while wait(1) do
player.leaderstats.Time.Value = player.leaderstats.Time.Value + 0 --Don't change it or it will make it go up twice
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local playerUserId = "Player"..player.UserId
local data = player.leaderstats.Time.Value
myDataStore:SetAsync(playerUserId, data)
end)
This is an edited time script, and the “pumpkins” is a FOLDER that keeps all the pumpkins.
For some reason this does not work, If anyone can help that would be great
local DataStoreService = game:GetService("DataStoreService"):GetDataStore("myDataStore")
debounce = false
pumpkins = game.Workspace.Pumpkins
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local timeingame = Instance.new("IntValue", leaderstats)
timeingame.Name = "Pumpkins"
timeingame.Value = DataStoreService:GetAsync(player.UserId, timeingame.Value) or 0
timeingame.Changed:Connect(function()
DataStoreService:SetAsync(player.UserId, timeingame.Value)
end)
game.Players.PlayerRemoving:Connect(function()
DataStoreService:SetAsync(player.UserId, timeingame.Value)
end)
for _,Pumpkin in pairs(pumpkins:GetChildren()) do
if Pumpkin:IsA("Part") then
Pumpkin.Touched:Connect(function()
if not debounce then
debounce = true
timeingame.Value += 1
wait(1)
debounce = false
end
end)
end
end
end)
You have an infinite loop (with no yield so it’s gonna crash) that makes a global function, which is connected to a Touched event outside of that scope so that probably doesn’t work.
I suggest you look into what a Scope is here. It’d prove useful I think. You also are connecting that function to a Touched event which won’t work, I assume your goal is that you’re constantly changing this KillOnTouch function to be every player “at the same time basically” so the connection works with every player, but that is just not how it works. Your while loop inside the player added connection is also completely useless.
Other than those extremely crucial points of how this won’t work, the actual root of the problem is one of two things, or a combination of the two:
PlayerAdded doesn’t ALWAYS account for if you load into the Studio place before the Server loads, so you need to make a function for the PlayerAdded connection, loop over every player using Players:GetPlayers() and THEN connecting that function to Players.PlayerAdded.
The other thing is that your Touched connection is only being connected once. If you wanna keep it simple, instead of having your while true do block, have a local function for that KillOnTouch inside your PlayerAdded connection then underneathe that do your script.Parent.Touched connection because you can connect more than one function to an event.
However, I suggest completely rewriting this script and having everything in one PlayerAdded connection, along with just a check of WHO touched the part instead of having it individually for each player (via Players:GetPlayerFromCharacter(characterModel) which can return nil so you need to check for that)
local Players = game:GetService("Players")
local function KillOnTouch(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if player then
player.leaderstats.Time.Value += 1
end
end)
for _, object in ipairs(pumpkins:GetChildren()) do
object.Touched:Connect(KillOnTouch)
end
lmao this is why you shouldn’t blatantly copy and paste scripts
just remove the .changed event you dont need to save everytime it changes, saving on leave is sufficient enough
also for player data i recommend profileservice
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local Pumpkins = Workspace.Pumpkins
local function OnPlayerAdded(Player:Player)
local Leaderstats = Instance.new("Folder", Player)
Leaderstats.Name = "leaderstats"
local Stat1 = Instance.new("IntValue", Leaderstats)
Stat1.Name = "Pumpkins"
end
Players.PlayerAdded:Connect(OnPlayerAdded)
for Index, Pumpkin in ipairs(Pumpkins:GetChildren()) do
local TouchedEvent = nil
local function OnTouched(Object:BasePart)
local Player = Players:GetPlayerFromCharacter(Object.Parent)
if Player then
TouchedEvent:Disconnect()
Player.leaderstats.Pumpkins.Value += 1
Pumpkin:Destroy()
end
end
TouchedEvent = Pumpkin.Touched:Connect(OnTouched)
end
I recommend using a ClickDetector instead but if you really want for it to be touch then I have provided both scripts,
I have provided a leaderboard script aswell
Leaderboard script
--//Services
local DataStoreService = game:GetService("DataStoreService")
local Players = game:getService("Players")
--//DataStore
local PumpkinData = DataStoreService:GetDataStore("PumpkinData")
--//Configuration
local PumpkinName = "Pumpkins"
local PumpkinStartingValue = 0
--//Script - Getting the Datastore
Players.PlayerAdded:Connect(function(player)
local UserData
local success, errMsg = pcall(function() --Uses pcall for when DataStore go down, prevents script errors.
UserData = PumpkinData:GetAsync(player.UserId)
end)
if success == false then --Protects old data when the DataStores go down
local doNotSave = Instance.new("Folder")
doNotSave.Name = "DoNotSave"
doNotSave.Parent = player
--When the player leaves the game with this Folder inside of them their data will not save/overwrite old data
else
print("Data load successful | User: "..player.Name)
end
local leaderstats = Instance.new("Folder") --Folder to hold leaderboard statistics, etc. Folder goes inside player
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Currency = Instance.new("IntValue")
Currency.Name = PumpkinName
Currency.Value = UserData or PumpkinStartingValue
Currency.Parent = leaderstats
end)
--//Script - Saving Datastore
Players.PlayerRemoving:Connect(function(player) --Saves data when player leaves the game
local PumpkimSavingPath = player.leaderstats:FindFirstChild(PumpkinName)
if player:FindFirstChild("DoNotSave") then --Detects if player's data is savable when old data cannot be loaded
warn("Player data was not saved to avoid data loss.")
else
PumpkinData:SetAsync(player.UserId, PumpkimSavingPath.Value) ----If the data was loaded successfully, the data will save
end
end)
Click detector
--// Variables
local Part = script.Parent.Parent
local ClickDetector = script.Parent
--// Script
ClickDetector.MouseClick:Connect(function(Player)
local leaderstats = Player.leaderstats
local PumpkinStat = leaderstats and leaderstats:WaitForChild("Pumpkins")
if PumpkinStat then
PumpkinStat.Value += 1
end
Part:Destroy --remove this if you dont want the part to be removed after the first click
end)
Touch
--// Services
local Players = game:GetService("Players")
--// Variables
local Part = script.Parent
--// Script
Players.PlayerAdded:Connect(function(Player)
Part.Touched:Connect(function()
local leaderstats = Player:WaitForChild("leaderstats")
local PumpkinStat = leaderstats and leaderstats:WaitForChild("Pumpkins")
if PumpkinStat then
PumpkinStat.Value += 1
end
Part:Destroy() --remove this if you dont want the part to be removed after the first touch
end)
end)
Why do you need to make a connection with PlayerAdded and create a leaderstats and pumpkins while already having it on a different script? Also for the while loop that will obviously going to force crash the player/client. As for the function KillOnTouch I have no idea why is it necessary to be on a loop, also the function is a global function, meaning other script will be able to access and modify this.
I recommend that you only have a single script that handles the touch event or whatever event that you are using, in this case touched. Like what I post on the last post.
If in any case that an object was added and you want to also add a connection with touch then you can just check if a descendant was added/make a connection.
That’s pumpkin. Your entire code is updating, saving, and setting the Time value, not Pumpkins value. Are you sure that Time value is the one that you want to change or Pumpkin?