Чтобы сделать Obby в Roblox Studio, соберите маршрут из платформ, пронумеруйте чекпоинты и храните текущий этап игрока в leaderstats.Stage. Серверный Script будет возвращать персонажа к последней достигнутой точке, а KillBrick отправит его на повторную попытку.
Obby, сокращение от obstacle course, это полоса препятствий. Игрок прыгает по платформам, избегает опасных деталей и доходит до финиша. Без чекпоинтов одна ошибка возвращает его в самое начало, поэтому сначала построим систему этапов, затем добавим опасность.
Платформы идут от простых прыжков к узким и движущимся участкам.
Детали 1, 2, 3 сохраняют текущий Stage строго по порядку.
После смерти Character появляется на четыре studs выше последней точки.
Из чего собрать первый Obby
Для первого рабочего уровня хватит пяти этапов. Один этап должен проверять один навык: обычный прыжок, расстояние, точность, обход опасности или движение по узкой платформе. Если смешать всё сразу, вы не поймёте, где трасса стала непроходимой.
| Объект | Количество | Свойства | Зачем нужен |
|---|---|---|---|
| Start | 1 | Anchored, CanCollide | Безопасное начало маршрута |
| Platforms | 8-15 | Anchored | Сами препятствия |
| Checkpoints | 5 | Имена 1, 2, 3, 4, 5 | Сохранение текущего Stage |
| KillBrick | 1-3 | Anchored, CanTouch | Смерть при касании |
| Finish | 1 | Можно использовать checkpoint 5 | Понятный конец уровня |
Между двумя чекпоинтами ставьте два или три препятствия. Игрок повторяет понятный короткий участок, а не половину всей карты.

Каждый новый Stage добавляет одну сложность, поэтому трассу удобно тестировать и поправлять.
Постройте маршрут и расставьте чекпоинты
Начните с Baseplate или пустого шаблона. Все игровые детали закрепите через Anchored = true, иначе физика уронит трассу при запуске. Для чекпоинтов используем обычные Parts, чтобы точку возврата полностью контролировал код.
- В
Workspaceсоздайте FolderCheckpoints. Внутрь добавьте пять Parts и назовите их1,2,3,4,5. - Поставьте checkpoint 1 на старт, checkpoint 5 на финиш. Все детали сделайте зелёными, включите
Anchored,CanCollideиCanTouch. - Между точками добавьте платформы. Сначала оставьте расстояния небольшими и проверьте путь обычным персонажем без ускорения.
- В
ServerScriptServiceсоздайте обычныйScriptс именемCheckpointManager.
Не делайте первые платформы слишком маленькими. Запустите Play и пройдите маршрут пять раз. Если один и тот же прыжок срывается чаще остальных, увеличьте площадку или уменьшите расстояние, а уже потом добавляйте KillBrick.
Код чекпоинтов и возврата на последний Stage
CheckpointManager создаёт игроку leaderstats и IntValue Stage со значением 1. Касание следующей по номеру точки обновляет Stage. После каждой новой модели Character скрипт находит сохранённый номер и переносит персонажа над соответствующей деталью.
local Players = game:GetService("Players")
local checkpoints = workspace:WaitForChild("Checkpoints")
local START_STAGE = 1
local function moveToCurrentStage(player, character)
local rootPart = character:WaitForChild("HumanoidRootPart", 5)
if not rootPart then
return
end
local leaderstats = player:FindFirstChild("leaderstats")
local stage = leaderstats and leaderstats:FindFirstChild("Stage")
local checkpoint = stage and checkpoints:FindFirstChild(tostring(stage.Value))
if checkpoint and checkpoint:IsA("BasePart") then
character:PivotTo(checkpoint.CFrame * CFrame.new(0, 4, 0))
end
end
local function setupPlayer(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local stage = Instance.new("IntValue")
stage.Name = "Stage"
stage.Value = START_STAGE
stage.Parent = leaderstats
player.CharacterAdded:Connect(function(character)
moveToCurrentStage(player, character)
end)
if player.Character then
task.spawn(moveToCurrentStage, player, player.Character)
end
end
local function connectCheckpoint(checkpoint)
local checkpointNumber = tonumber(checkpoint.Name)
if not checkpointNumber then
warn("Checkpoint name must be a number: " .. checkpoint.Name)
return
end
checkpoint.Touched:Connect(function(otherPart)
local character = otherPart:FindFirstAncestorOfClass("Model")
local player = character and Players:GetPlayerFromCharacter(character)
if not player then
return
end
local leaderstats = player:FindFirstChild("leaderstats")
local stage = leaderstats and leaderstats:FindFirstChild("Stage")
if stage and checkpointNumber == stage.Value + 1 then
stage.Value = checkpointNumber
end
end)
end
for _, checkpoint in checkpoints:GetChildren() do
if checkpoint:IsA("BasePart") then
connectCheckpoint(checkpoint)
end
end
Players.PlayerAdded:Connect(setupPlayer)- При входе Stage равен 1, персонаж появляется над checkpoint 1.
- Касание checkpoint 2 меняет Stage на 2, касание checkpoint 4 раньше времени ничего не делает.
- После Reset Character возвращается над последней достигнутой точкой.
- У двух игроков Stage меняется независимо.

Условие Stage + 1 запрещает перепрыгнуть несколько этапов касанием далёкого чекпоинта.
Значение Stage живёт, пока игрок находится на сервере. Чтобы вернуть его к этапу после нового входа в игру, подключите серверное сохранение из статьи про DataStore и прогресс Roblox.
Добавьте KillBrick и протестируйте цикл ошибки
Создайте красную деталь под сложным прыжком, включите Anchored и CanTouch, затем вставьте внутрь обычный Script. KillBrick должен только убить Humanoid. Возврат к этапу уже выполнит CharacterAdded из CheckpointManager.
local killBrick = script.Parent
local killed = {}
local function onTouched(otherPart)
local character = otherPart:FindFirstAncestorOfClass("Model")
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
if not humanoid or killed[humanoid] then
return
end
killed[humanoid] = true
humanoid.Health = 0
task.delay(1, function()
killed[humanoid] = nil
end)
end
killBrick.Touched:Connect(onTouched)Игрок проходит checkpoint 3, падает на KillBrick, умирает и появляется над checkpoint 3. Stage не сбрасывается, а опасная деталь не пытается убить один Humanoid несколько раз подряд.
Подробный разбор поиска Humanoid и защиты от повторных касаний есть в отдельной статье про рабочий KillBrick в Roblox. Для Obby достаточно короткой версии выше.

Тест считается пройденным, когда система одинаково ведёт себя после смерти, пропуска точки и при двух игроках.
Почему чекпоинт не сохраняется или игрок застревает
Откройте View, Output и повторите конкретную ошибку. Затем посмотрите Stage в таблице игроков. Если номер обновился, проблема в точке появления. Если номер остался прежним, проверяйте имя детали и событие Touched.
Checkpoint назван Stage2 вместо 2, выключен CanTouch или лежит вне папки Checkpoints.
Уменьшен сдвиг CFrame.new(0, 4, 0) или checkpoint слишком толстый. Поднимите точку возврата.
В коде стоит сравнение checkpointNumber > stage.Value. Оставьте точную проверку stage.Value + 1.
Как сделать Obby в Roblox Studio?
Obby собирают из закреплённых платформ, опасных деталей и пронумерованных чекпоинтов. Серверный Script хранит текущий Stage и возвращает персонажа к нужной точке после смерти.
Как сделать чекпоинт в Roblox Studio?
Чекпоинт делают обычным Part с числовым именем. Событие Touched на сервере находит Player и увеличивает его IntValue Stage, если достигнут следующий номер.
Как возродить игрока на последнем чекпоинте?
После CharacterAdded найдите Part с именем текущего Stage и вызовите character:PivotTo(checkpoint.CFrame * CFrame.new(0, 4, 0)).
Как запретить пропуск чекпоинтов в Obby?
Пропуск запрещает сравнение checkpointNumber == stage.Value + 1. Далёкий checkpoint не обновит Stage, пока предыдущий этап не пройден.
Как сохранить Stage после выхода из игры?
Stage после выхода сохраняют через DataStoreService на сервере. Без DataStore значение сбрасывается на START_STAGE при новом подключении.
Сделайте шестой checkpoint и добавьте одно новое правило: исчезающую платформу, движущуюся деталь или таймер. Если код падает, ищите первую строку по инструкции по ошибкам Roblox Studio, а базовые события освежите в статье про первый скрипт Roblox.
Таблицы, функции и условия из CheckpointManager можно спокойно разобрать в бесплатном курсе Lua. Дальнейшие механики и порядок обучения собраны в дорожной карте Lua-разработчика для Roblox.
