Question about script

I have a checkpoint script(that I don’t fully understand) that basically changes the player’s leaderstat and if they die they respawn at the latest checkpoint they hit. My question is that when I manually go in and change the player’s leaderstat and reset theyre character, they don’t spawn at the checkpoint correlating to that leaderstat so how can I modify the code to make it so the player spawns at the correct checkpoint because of the leaderstats instead of the checkpoint they last touched, and the leaderstat just being an extra thing. Here is the code:

local Players = game:GetService("Players")

local Checkpoints = workspace:WaitForChild("Checkpoints")
local inGameStartupPlayers = {}
local CurrentStage = {}
local TouchDb = {}

local function NewCharacter(player, char)
	local TempCurrentStage = CurrentStage[player.UserId]
	if TempCurrentStage ~= nil then
		local TempCheckpoint = Checkpoints:FindFirstChild(TempCurrentStage)
		if TempCheckpoint ~= nil then
			repeat wait(0.1) until char.PrimaryPart ~= nil
			char:SetPrimaryPartCFrame(CFrame.new(TempCheckpoint.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(TempCheckpoint.Orientation.Y) + math.rad(0), 0))
		end
	end
end

local function NewPlayer(player)
	CurrentStage[player.UserId] = 1

	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	local Stage = Instance.new("IntValue", leaderstats)
	Stage.Name = "Level"
	Stage.Value = 1

	local TempChar = player.Character
	if TempChar ~= nil then
		NewCharacter(player, TempChar)
	end
	player.CharacterAdded:Connect(function(char)
		NewCharacter(player, char)
	end)
end

Players.PlayerAdded:Connect(function(player)
	if inGameStartupPlayers[player] == nil then
		NewPlayer(player)
	end
end)

Players.PlayerRemoving:Connect(function(player)
	CurrentStage[player.UserId] = nil
end)

for i,v in pairs(Checkpoints:GetChildren()) do
	local StageNum = tonumber(v.Name)
	v.Touched:Connect(function(hit)
		local char = hit.Parent
		if char ~= nil then
			local Humanoid = char:FindFirstChildOfClass("Humanoid")
			if Humanoid ~= nil and Humanoid.Health > 0 then
				local player = Players:GetPlayerFromCharacter(char)
				if player ~= nil and (TouchDb[player.UserId] or 0) + 1 <= os.time() then
					TouchDb[player.UserId] = os.time()
					local TempCurrentStage = CurrentStage[player.UserId]
					if TempCurrentStage < StageNum or TempCurrentStage > StageNum then
						CurrentStage[player.UserId] = StageNum
						local TempLeaderstats = player:FindFirstChild("leaderstats")
						if TempLeaderstats ~= nil then
							local TempStage = TempLeaderstats:FindFirstChild("Level")
							if TempStage ~= nil then
								TempStage.Value = StageNum
							end
						end
					end
				end
			end
		end
	end)
end

inGameStartupPlayers = Players:GetPlayers()
for i,v in pairs(inGameStartupPlayers) do
	spawn(function()
		NewPlayer(v)
	end)
end

inGameStartupPlayers = {}
1 Like
local Players = game:GetService("Players")

local Checkpoints = workspace:WaitForChild("Checkpoints")
local inGameStartupPlayers = {}
local CurrentStage = {}
local TouchDb = {}

local function NewCharacter(player, char)
	local leaderstats = player:FindFirstChild("leaderstats")
	if leaderstats then
		local Level = leaderstats:FindFirstChild("Level")
		if Level then
			local TempCurrentStage = Level
			if TempCurrentStage.Value ~= nil then
				local TempCheckpoint = Checkpoints:FindFirstChild(TempCurrentStage.Value)
				if TempCheckpoint ~= nil then
					repeat wait(0.1) until char.PrimaryPart ~= nil
					char:SetPrimaryPartCFrame(CFrame.new(TempCheckpoint.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(TempCheckpoint.Orientation.Y) + math.rad(0), 0))
				end
			end
		end
	end
end

local function NewPlayer(player)
	CurrentStage[player.UserId] = 1

	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	local Stage = Instance.new("IntValue", leaderstats)
	Stage.Name = "Level"
	Stage.Value = 1

	local TempChar = player.Character
	if TempChar ~= nil then
		NewCharacter(player, TempChar)
	end
	player.CharacterAdded:Connect(function(char)
		NewCharacter(player, char)
	end)
end

Players.PlayerAdded:Connect(function(player)
	if inGameStartupPlayers[player] == nil then
		NewPlayer(player)
	end
end)

Players.PlayerRemoving:Connect(function(player)
	CurrentStage[player.UserId] = nil
end)

for i,v in pairs(Checkpoints:GetChildren()) do
	local StageNum = tonumber(v.Name)
	v.Touched:Connect(function(hit)
		local char = hit.Parent
		if char ~= nil then
			local Humanoid = char:FindFirstChildOfClass("Humanoid")
			if Humanoid ~= nil and Humanoid.Health > 0 then
				local player = Players:GetPlayerFromCharacter(char)
				if player ~= nil and (TouchDb[player.UserId] or 0) + 1 <= os.time() then
					TouchDb[player.UserId] = os.time()
					local TempCurrentStage = CurrentStage[player.UserId]
					if TempCurrentStage < StageNum or TempCurrentStage > StageNum then
						CurrentStage[player.UserId] = StageNum
						local TempLeaderstats = player:FindFirstChild("leaderstats")
						if TempLeaderstats ~= nil then
							local TempStage = TempLeaderstats:FindFirstChild("Level")
							if TempStage ~= nil then
								TempStage.Value = StageNum
							end
						end
					end
				end
			end
		end
	end)
end

inGameStartupPlayers = Players:GetPlayers()
for i,v in pairs(inGameStartupPlayers) do
	spawn(function()
		NewPlayer(v)
	end)
end

inGameStartupPlayers = {}

I checked - it works, if you want to zero a person, in the console (F9) write game:GetService("Players")["PLAYERNAME"].leaderstats.Level.Value = 1

1 Like

Thanks, I appreciate the answer but, can you explain the changes?

you need to do it on the server side if you are doing it at runtime when

basically: when you run the game and make a change its only going to do it locally to you so when you reset the server isnt going to see the local change you made, so you need to click the blue button at the top of studio to go onto the server side, change the value you want and then click the green button again to go back onto your character, reset and you should be at ur checkpoint
image
to play
image
to switch to server side
image
to switch to client

also if youve made the change in a local script its the same scenario make the change in a server script

local function NewCharacter(player, char)
	local TempCurrentStage = CurrentStage[player.UserId]
	if TempCurrentStage ~= nil then
		local TempCheckpoint = Checkpoints:FindFirstChild(TempCurrentStage)
		if TempCheckpoint ~= nil then
			repeat wait(0.1) until char.PrimaryPart ~= nil
			char:SetPrimaryPartCFrame(CFrame.new(TempCheckpoint.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(TempCheckpoint.Orientation.Y) + math.rad(0), 0))
		end
	end
end

old

local function NewCharacter(player, char)
	local leaderstats = player:FindFirstChild("leaderstats")
	if leaderstats then
		local Level = leaderstats:FindFirstChild("Level")
		if Level then
			local TempCurrentStage = Level
			if TempCurrentStage.Value ~= nil then
				local TempCheckpoint = Checkpoints:FindFirstChild(TempCurrentStage.Value)
				if TempCheckpoint ~= nil then
					repeat wait(0.1) until char.PrimaryPart ~= nil
					char:SetPrimaryPartCFrame(CFrame.new(TempCheckpoint.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(TempCheckpoint.Orientation.Y) + math.rad(0), 0))
				end
			end
		end
	end
end

new
the new part is value oriented, not local table oriented

2 Likes