Roblox · Дополнительное
Пронумерованные чекпоинты 1, 2, 3… — площадка с флажком. Встал на следующую по порядку — после смерти появляешься на ней, а не на старте. Номер этапа виден в таблице игроков (колонка Stage). Перепрыгнуть через чекпоинт нельзя.
Синим — что нужно создать.
Workspace ├─ SpawnLocation (SpawnLocation) — старт — этап 0 └─ Checkpoints (Folder) ├─ 1 (Model) — имя — только номер; PrimaryPart = Pad │ ├─ Pad (Part) — площадка, Anchored │ │ └─ Reached (Sound) — звук «чекпоинт взят» (по желанию) │ ├─ Pole (Part) — столбик флажка, Anchored │ └─ Flag (Part) — флажок, Anchored, CanCollide выкл. ├─ 2 (Model) — такой же: Pad, Pole, Flag └─ 3 (Model) ServerScriptService └─ CheckpointServer (Script)
Где: ServerScriptService · Script
Зачем: Считает этап игрока и возрождает на последнем взятом чекпоинте.
-- игроки
local Players = game:GetService("Players")
-- папка с чекпоинтами-моделями 1, 2, 3…
local checkpoints = workspace:WaitForChild("Checkpoints")
-- включает один чекпоинт: модель с площадкой Pad и флажком
local function Setup(checkpoint)
-- площадка, на которую встают
local pad = checkpoint:FindFirstChild("Pad")
-- площадки нет — чекпоинт собран неправильно
if not pad then
-- подсказка в Output; остальные чекпоинты работают
warn("Чекпоинт " .. checkpoint.Name .. ": внутри модели нужна деталь Pad")
-- этот пропускаем
return
-- конец проверки
end
-- площадки что-то коснулось
pad.Touched:Connect(function(otherPart)
-- модель, которой принадлежит деталь
local character = otherPart:FindFirstAncestorOfClass("Model")
-- это персонаж игрока?
local player = character and Players:GetPlayerFromCharacter(character)
-- нет — пропускаем
if not player then return end
-- его Humanoid
local humanoid = character:FindFirstChildOfClass("Humanoid")
-- мёртвый — не считается
if not humanoid or humanoid.Health <= 0 then return end
-- таблица игрока
local stats = player:FindFirstChild("leaderstats")
-- номер этапа
local stage = stats and stats:FindFirstChild("Stage")
-- номер чекпоинта из имени модели
local number = tonumber(checkpoint.Name)
-- нет этапа или имя не число
if not stage or not number then return end
-- только следующий по порядку — пропустить нельзя
if number == stage.Value + 1 then
-- новый этап
stage.Value = number
-- звук «чекпоинт взят»
local sound = pad:FindFirstChild("Reached")
-- есть — играем
if sound then sound:Play() end
-- конец проверки
end
-- конец обработчика
end)
-- конец функции
end
-- все чекпоинты в папке
for _, checkpoint in pairs(checkpoints:GetChildren()) do
-- включаем
Setup(checkpoint)
-- конец перебора
end
-- игрок зашёл
Players.PlayerAdded:Connect(function(player)
-- таблица уже есть (например, от кошелька)?
local stats = player:FindFirstChild("leaderstats")
-- нет
if not stats then
-- создаём
stats = Instance.new("Folder")
-- имя, которое понимает Roblox — колонка в таблице игроков
stats.Name = "leaderstats"
-- в игрока
stats.Parent = player
-- конец проверки
end
-- номер этапа
local stage = Instance.new("IntValue")
-- колонка Stage
stage.Name = "Stage"
-- в таблицу
stage.Parent = stats
-- персонаж появился (в начале и после смерти)
player.CharacterAdded:Connect(function(character)
-- чекпоинт текущего этапа
local checkpoint = checkpoints:FindFirstChild(tostring(stage.Value))
-- этап 0 — обычный SpawnLocation
if not checkpoint or not checkpoint:FindFirstChild("Pad") then return end
-- ждём, пока персонаж загрузится
character:WaitForChild("HumanoidRootPart")
-- кадр: Roblox сначала сам ставит персонажа на SpawnLocation
task.wait()
-- переносим на площадку чекпоинта
character:PivotTo(checkpoint.Pad.CFrame + Vector3.new(0, 4, 0))
-- конец обработчика
end)
-- конец обработчика
end)Запусти Play (или Run) и убедись: