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

Ключ и дверь

Головоломка: найди ключ — он спрятан где-то на карте, — и дверь откроется. Без ключа на двери «Нужен ключ!». Ключ тратится, а на карте через время появляется снова — для других игроков.

Структура

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

Workspace
└─ KeyDoor (Model)
   ├─ WallL, WallR (Part) — стены по бокам
   ├─ Door (Part) — дверь
   │  └─ HintGui (SurfaceGui) — HintText (TextLabel)
   ├─ Key (Part) — ключ, CanCollide выкл.
   ├─ Configuration (Configuration) — OpenTime, KeyRespawn
   └─ KeyDoorServer (Script)

Шаги

  1. Дверь «Door» в проёме между стенами. На ней SurfaceGui «HintGui» с TextLabel «HintText» — надпись на поверхности детали (Face — сторона, к игроку).
  2. Ключ — деталь или модель из Toolbox (одна деталь «Key», CanCollide выкл.). Спрячь его: за домом, на крыше, под водой.
  3. Ключ хранится как атрибут игрока HasKey. В Алгоритмике ключ пропадал для всех навсегда — здесь он возвращается через KeyRespawn секунд.
  4. Дверь уезжает вверх (TweenService) на OpenTime секунд и опускается.
  5. Усложни: два ключа (HasKey1, HasKey2), ключ в сундуке (Дополнительное → «Сундук»), загадка с кодом («Дверь с кодом»).

Скрипты

KeyDoorServer

Где: Workspace → KeyDoor · Script
Зачем: Ключ, дверь, надпись.

-- игроки
local Players = game:GetService("Players")
-- плавность
local TS = game:GetService("TweenService")
-- модель KeyDoor
local model = script.Parent
-- ключ на карте
local key = model:WaitForChild("Key")
-- дверь
local door = model:WaitForChild("Door")
-- надпись на двери
local hint = door:WaitForChild("HintGui"):WaitForChild("HintText")
-- OpenTime, KeyRespawn
local config = model:WaitForChild("Configuration")
-- дверь закрыта
local closedCF = door.CFrame
-- дверь поднята
local openCF = closedCF + Vector3.new(0, door.Size.Y, 0)
-- дверь открывается
local opening = false
-- вращение ключа
local spin = 0

-- коснулись ключа
key.Touched:Connect(function(hit)
    -- игрок
    local player = Players:GetPlayerFromCharacter(hit.Parent)
    -- ключ уже взят или у игрока есть
    if not player or key.Transparency > 0 or player:GetAttribute("HasKey") then return end
    -- ключ у игрока
    player:SetAttribute("HasKey", true)
    -- ключ пропал с карты
    key.Transparency = 1
    -- через время появится снова — для других
    task.delay(config.KeyRespawn.Value, function() key.Transparency = 0 end)
-- конец функции
end)
-- коснулись двери
door.Touched:Connect(function(hit)
    -- игрок
    local player = Players:GetPlayerFromCharacter(hit.Parent)
    -- не игрок или уже открывается
    if not player or opening then return end
    -- ключа нет
    if not player:GetAttribute("HasKey") then
        -- подсказка
        hint.Text = "Нужен ключ!"
        -- не открываем
        return
    -- конец проверки
    end
    -- открываем
    opening = true
    -- ключ потрачен
    player:SetAttribute("HasKey", false)
    -- надпись
    hint.Text = "Открыто"
    -- дверь уезжает вверх
    TS:Create(door, TweenInfo.new(1), {CFrame = openCF}):Play()
    -- открыта
    task.wait(config.OpenTime.Value)
    -- закрывается
    TS:Create(door, TweenInfo.new(1), {CFrame = closedCF}):Play()
    -- доехала
    task.wait(1)
    -- надпись
    hint.Text = "Закрыто"
    -- можно снова
    opening = false
-- конец функции
end)
-- каждый кадр
game:GetService("RunService").Heartbeat:Connect(function(dt)
    -- угол
    spin += dt * 2
    -- ключ медленно крутится — его заметно
    key.CFrame = CFrame.new(key.Position) * CFrame.Angles(0, spin, 0)
-- конец функции
end)

Проверка

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

Собрать ключ и дверь одной командой