Roblox · Дополнительное
У двери кодовая панель: E — открывается окно с кнопками 0–9. Набрал верный код — «ОТКРЫТО», дверь уезжает и через 4 секунды закрывается. Код хранится на сервере — подсмотреть его нельзя.
Синим — что нужно создать.
Workspace └─ CodeDoor (Model) ├─ Door (Part) ├─ Keypad (Part) — панель │ └─ ProximityPrompt (ProximityPrompt) — «Ввести код» ├─ TryCode (RemoteFunction) — клиент спрашивает — сервер проверяет ├─ Configuration (Configuration) — OpenTime └─ CodeDoorServer (Script) — код — в первой строке StarterGui └─ KeypadGui (ScreenGui) — ResetOnSpawn выкл. └─ Frame (Frame) — Visible выкл. ├─ Display (TextLabel) — экранчик ├─ Grid (Frame) — кнопки создаёт скрипт │ └─ UIGridLayout (UIGridLayout) — SortOrder = LayoutOrder └─ Close (TextButton) — крестик StarterPlayer → StarterPlayerScripts └─ KeypadLocal (LocalScript)
Где: Workspace → CodeDoor · Script
Зачем: Проверка кода и открытие.
-- плавное движение
local TS = game:GetService("TweenService")
-- модель двери с кодом
local model = script.Parent
-- дверь
local door = model:WaitForChild("Door")
-- игрок присылает код
local tryCode = model:WaitForChild("TryCode")
-- настройки
local config = model:WaitForChild("Configuration")
-- код двери — здесь игроки его не увидят: текст серверного скрипта им не отправляется
local CODE = "1234"
-- закрыта
local closedCF = door.CFrame
-- время прошлой попытки каждого игрока
local last = {}
-- открыта?
local open = false
-- открыть и через время закрыть
local function Open()
-- уже открыта
if open then return end
-- открыта
open = true
-- уезжает вверх
TS:Create(door, TweenInfo.new(1), {CFrame = closedCF + Vector3.new(0, door.Size.Y, 0)}):Play()
-- стоит открытой
task.wait(config.OpenTime.Value)
-- закрывается
TS:Create(door, TweenInfo.new(1), {CFrame = closedCF}):Play()
-- доехала
task.wait(1)
-- закрыта
open = false
-- конец функции
end
-- игрок нажал OK
tryCode.OnServerInvoke = function(player, code)
-- прислали не текст
if typeof(code) ~= "string" then return false end
-- не чаще двух попыток в секунду — перебором не взломать
if os.clock() - (last[player] or 0) < 0.5 then return false end
-- запоминаем
last[player] = os.clock()
-- где игрок
local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
-- издалека не открыть
if not root or (root.Position - door.Position).Magnitude > 20 then return false end
-- неверно
if code ~= CODE then return false end
-- открываем, не задерживая ответ
task.spawn(Open)
-- верно
return true
-- конец функции
endГде: StarterPlayer → StarterPlayerScripts · LocalScript
Зачем: Окно с кнопками и отправка кода.
-- все надписи ProximityPrompt
local PPS = game:GetService("ProximityPromptService")
-- этот игрок
local player = game.Players.LocalPlayer
-- окно кодового замка
local gui = player:WaitForChild("PlayerGui"):WaitForChild("KeypadGui")
-- окно
local frame = gui:WaitForChild("Frame")
-- экранчик
local display = frame:WaitForChild("Display")
-- место для кнопок
local grid = frame:WaitForChild("Grid")
-- крестик
local closeButton = frame:WaitForChild("Close")
-- не больше 6 цифр
local MAX = 6
-- дверь, у которой стоим
local current = nil
-- набранный код
local code = ""
-- написать на экранчике
local function Show(text, color)
-- текст
display.Text = text
-- цвет
display.TextColor3 = color or Color3.new(1, 1, 1)
-- конец функции
end
-- нажата кнопка
local function Press(key)
-- окно не открыто
if not current then return end
-- стереть
if key == "C" then
-- код пустой
code = ""
-- экран пустой
Show("")
-- проверить
elseif key == "OK" then
-- сервер сравнит с настоящим кодом
local ok = current.TryCode:InvokeServer(code)
-- набор сбрасываем
code = ""
-- верно
if ok then
-- зелёным
Show("ОТКРЫТО", Color3.fromRGB(90, 230, 120))
-- пусть прочитает
task.wait(0.8)
-- закрываем окно
frame.Visible = false
-- дверь забыли
current = nil
-- неверно
else
-- красным
Show("НЕВЕРНО", Color3.fromRGB(240, 80, 80))
-- конец проверки
end
-- цифра, и место ещё есть
elseif #code < MAX then
-- добавляем цифру
code ..= key
-- показываем точками
Show(string.rep("•", #code))
-- конец выбора
end
-- конец функции
end
-- 12 кнопок: скрипт создаёт их сам
for i, key in ipairs({"1", "2", "3", "4", "5", "6", "7", "8", "9", "C", "0", "OK"}) do
-- кнопка
local button = Instance.new("TextButton")
-- имя
button.Name = key
-- надпись
button.Text = key
-- порядок в сетке
button.LayoutOrder = i
-- текст по размеру
button.TextScaled = true
-- жирный
button.Font = Enum.Font.GothamBold
-- белый
button.TextColor3 = Color3.new(1, 1, 1)
-- OK зелёная, C красная
button.BackgroundColor3 = key == "OK" and Color3.fromRGB(70, 170, 90) or key == "C" and Color3.fromRGB(190, 70, 70) or Color3.fromRGB(60, 60, 75)
-- в сетку
button.Parent = grid
-- нажатие
button.MouseButton1Click:Connect(function() Press(key) end)
-- конец перебора
end
-- крестик
closeButton.MouseButton1Click:Connect(function()
-- закрываем
frame.Visible = false
-- дверь забыли
current = nil
-- конец обработчика
end)
-- игрок нажал E у какой-то надписи
PPS.PromptTriggered:Connect(function(prompt)
-- модель, в которой надпись
local model = prompt.Parent and prompt.Parent.Parent
-- это не кодовый замок
if prompt.Parent.Name ~= "Keypad" or not model:FindFirstChild("TryCode") then return end
-- запоминаем дверь
current = model
-- набор с нуля
code = ""
-- экран пустой
Show("")
-- открываем окно
frame.Visible = true
-- конец обработчика
end)Запусти Play (или Run) и убедись: