Roblox · Дополнительное

Уровни и порталы

Игра из нескольких уровней: в конце каждого — портал на следующий. Номер уровня виден в таблице справа, а после смерти игрок появляется на своём уровне, а не в начале.

Структура

Синим — что нужно создать.

Workspace
└─ Levels (Folder)
   ├─ Start (Model) — Portal → StartPortal (Script) — с основной карты на 1 уровень
   └─ Level1, Level2, Level3 (Model) — номер в имени
      ├─ Floor (Part) — площадка уровня
      ├─ Spawn (Part) — начало уровня
      └─ Portal (Part) — в конце; CanCollide выкл. (у последнего нет)
ServerScriptService
└─ LevelsServer (Script)

Шаги

  1. Левел-дизайн: каждый уровень учит чему-то одному и чуть сложнее прошлого; в конце — награда или переход.
  2. Сначала нарисуй карту уровней на бумаге: что на каждом, где портал, как они связаны.
  3. Каждый уровень — модель «Level1», «Level2»… с деталями «Spawn» (начало) и «Portal» (переход дальше). Уровни можно строить далеко друг от друга или на разной высоте — игрок не видит соседние.
  4. LevelsServer берёт номер из имени модели: портал в Level2 ведёт к Spawn в Level3. Добавить уровень — скопировать модель и поменять цифру.
  5. leaderstats → Level запоминает самый дальний уровень; после смерти игрок переносится туда (CharacterAdded).
  6. Чтобы прогресс не терялся после выхода, сохрани Level в DataStore (как в Системы → «Монеты»).

Скрипты

LevelsServer

Где: ServerScriptService · Script
Зачем: Порталы и прогресс.

-- игроки
local Players = game:GetService("Players")
-- Level1, Level2… — у каждого Spawn и Portal
local levels = workspace:WaitForChild("Levels")
-- игрок → идёт перенос
local busy = {}

-- точка появления уровня
local function Spawn(n)
    -- уровень
    local level = levels:FindFirstChild("Level" .. n)
    -- его точка
    return level and level:FindFirstChild("Spawn")
-- конец функции
end
-- перенести на уровень
local function Send(player, n)
    -- куда
    local spawn = Spawn(n)
    -- переносим
    if spawn and player.Character then player.Character:PivotTo(spawn.CFrame + Vector3.new(0, 3, 0)) end
-- конец функции
end

-- игрок зашёл
local function Setup(player)
    -- таблица справа
    local stats = player:FindFirstChild("leaderstats") or Instance.new("Folder")
    -- имя
    stats.Name = "leaderstats"
    -- в игрока
    stats.Parent = player
    -- уровень
    local level = Instance.new("IntValue")
    -- имя
    level.Name = "Level"
    -- первый
    level.Value = 1
    -- в таблицу
    level.Parent = stats
    -- возродился
    player.CharacterAdded:Connect(function(character)
        -- персонаж готов
        character:WaitForChild("HumanoidRootPart")
        -- кадр — Roblox сначала ставит на SpawnLocation
        task.wait()
        -- на свой уровень, а не в начало (на первом — обычный старт)
        if level.Value > 1 then Send(player, level.Value) end
    -- конец функции
    end)
-- конец функции
end
-- новые игроки
Players.PlayerAdded:Connect(Setup)
-- кто зашёл раньше скрипта
for _, player in ipairs(Players:GetPlayers()) do Setup(player) end

-- каждый уровень
for _, level in ipairs(levels:GetChildren()) do
    -- портал в конце
    local portal = level:FindFirstChild("Portal")
    -- номер уровня из имени
    local n = tonumber(level.Name:match("%d+"))
    -- есть
    if portal and n then
        -- вошли в портал
        portal.Touched:Connect(function(hit)
            -- игрок
            local player = Players:GetPlayerFromCharacter(hit.Parent)
            -- уже переносим или уровня дальше нет
            if not player or busy[player] or not Spawn(n + 1) then return end
            -- один раз
            busy[player] = true
            -- его уровень
            local value = player.leaderstats.Level
            -- открыт следующий
            value.Value = math.max(value.Value, n + 1)
            -- переносим
            Send(player, n + 1)
            -- пауза
            task.wait(1)
            -- готово
            busy[player] = nil
        -- конец функции
        end)
    -- конец проверки
    end
-- конец перебора
end

StartPortal

Где: Workspace → Levels → Start → Portal · Script
Зачем: С карты на первый уровень.

-- коснулись портала
script.Parent.Touched:Connect(function(hit)
    -- игрок?
    local player = game.Players:GetPlayerFromCharacter(hit.Parent)
    -- на первый уровень
    if player then hit.Parent:PivotTo(workspace.Levels.Level1.Spawn.CFrame + Vector3.new(0, 3, 0)) end
-- конец функции
end)

Проверка

Запусти Play (или Run) и убедись:

Собрать уровни одной командой