Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Touching a checkpoint comes up with an error, how do I fix this?

Hello! I'm making an obby and I have several problems with my code. First of all, my script is meant to display the player's stage on the leaderboard, and it works, however the stage value won't increase when touching another checkpoint, it just stays at 1. Whenever I touch a checkpoint an error shows up reading, "ServerScriptService.StageScript:23: attempt to index nil with 'leaderstats'".

Here's the script.

local Stages = workspace:WaitForChild("Stages")

for i,Stage in pairs(Stages:GetChildren()) do
		
	Stage.Touched:Connect(function(touch)
			
		local humanoid
		
		if touch.Parent:FindFirstChild("Humanoid") then
			
			humanoid = touch.Parent.Humanoid
		end
		
		if touch.Parent and touch.Parent.Parent:FindFirstChild("Humanoid") then
			
			humanoid = touch.Parent.Parent.Humanoid
		end
		
		if humanoid then
			
			local player = game.Players:GetPlayerFromCharacter(humanoid.Parent)
			
			local PlayerStage = player.leaderstats.Stage.Value
			
			if tonumber(Stage.Name) == PlayerStage + 1 then
				
				player.leaderstats.Stage.Value = player.leaderstats.Stage.Value + 1
			
			elseif tonumber(Stage.Name) > PlayerStage + 1 then
				
				humanoid.Health = 0
			end
		end
	end)
end

Secondly, I also have an autosaving script to save the player's stage so when they rejoin, they will be at the stage they were at when they left. I'm not sure if it works as the stage value stays at 1. However, I know it's part of the problem because the player's "leaderstats" folder is created here.

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local SaveDataStore = DataStoreService:GetDataStore("SaveData")


local function SavePlayerData(player)
	
	local success,errormsg = pcall(function()
	
		local SaveData = {}
		
		for i,stats in pairs(player.leaderstats:GetChildren()) do
			
			SaveData[stats.Name] = stats.Value
		end	
		SaveDataStore:SetAsync(player.UserId,SaveData)
	end)
	
	if not success then 
		return errormsg
	end			
end	


Players.PlayerAdded:Connect(function(player)
	
	local Stats = Instance.new("Folder")
	Stats.Name = "leaderstats"
	Stats.Parent = player
	
	local Stage = Instance.new("StringValue")
	Stage.Name = "Stage"
	Stage.Parent = Stats
	Stage.Value = 1
	
	local Data = SaveDataStore:GetAsync(player.UserId)
	
	if Data then
			
		print(Data.Stage)
		
		for i,stats in pairs(Stats:GetChildren()) do
			
			stats.Value = Data[stats.Name]		
		end			
	else		
		print(player.Name .. " has no data.")			
	end
	
	
	player.CharacterAdded:Connect(function(character)
		
		local Humanoid = character:WaitForChild("Humanoid")
		local Torso = character:WaitForChild("HumanoidRootPart")
		
		wait()
		
		if Torso and Humanoid then
			if Stage.Value ~= 0 then
				
				local StagePart = workspace.Stages:FindFirstChild(Stage.Value)
				Torso.CFrame = StagePart.CFrame + Vector3.new(0,1,0)					
			end	
		end	
	end)		
end)


Players.PlayerRemoving:Connect(function(player)
	
	local errormsg = SavePlayerData(player)
	
	if errormsg then	
		warn(errormsg)		
	end	
end)

game:BindToClose(function()
	for i,player in pairs(Players:GetPlayers()) do	
		
		local errormsg = SavePlayerData(player)
		if errormsg then
			warn(errormsg)
		end			
	end
	wait(2)	
end)

1 answer

✓ Accepted answer

Hello, Protigous! I think the problem is that you did not check if the part that got touched was a player. Try this:

local Stages = workspace:WaitForChild("Stages")

for i, Stage in pairs(Stages:GetChildren()) do

    Stage.Touched:Connect(function(touch)

        local humanoid

		local player = game.Players:GetPlayerFromCharacter(touch.Parent)

        if touch.Parent:FindFirstChild("Humanoid") then

            humanoid = touch.Parent.Humanoid
        end

        if touch.Parent and touch.Parent.Parent:FindFirstChild("Humanoid") then

            humanoid = touch.Parent.Parent.Humanoid
        end

        if humanoid and player then
            local PlayerStage = player.leaderstats.Stage.Value

            if tonumber(Stage.Name) == PlayerStage + 1 then

                player.leaderstats.Stage.Value = player.leaderstats.Stage.Value + 1

            elseif tonumber(Stage.Name) > PlayerStage + 1 then

                humanoid.Health = 0
            end
        end
    end)
end

I just added if humand and player then. If this helped you accept this answer.

2 comments

0

This works, thank you!

0

No problem.

This discussion is preserved as it was. New answers, comments, and votes are closed.