Roblox · Дополнительное
Прилавок: E — окно со списком товаров и ценами. «Купить» — монеты списываются, предмет в рюкзаке. Товары с пометкой KeepOnDeath остаются и после смерти.
Синим — что нужно создать.
Workspace └─ Shop (Model) — прилавок └─ Counter (Part) └─ ShopPrompt (ProximityPrompt) — имя важно ReplicatedStorage ├─ ShopItems (Folder) │ └─ Torch, Sword, … (Tool) — атрибуты Price и KeepOnDeath └─ BuyItem (RemoteFunction) ServerScriptService ├─ Coins (ModuleScript) — из раздела «Системы» └─ ShopServer (Script) StarterGui └─ ShopGui (ScreenGui) — ResetOnSpawn выкл. └─ Frame (Frame) — Visible выкл.: Title, List (ScrollingFrame + UIListLayout), Status, Close StarterPlayer → StarterPlayerScripts └─ ShopLocal (LocalScript)
Где: ServerScriptService · Script
Зачем: Проверяет монеты и выдаёт товар.
-- общее хранилище
local RS = game:GetService("ReplicatedStorage")
-- модуль монет (раздел «Системы»)
local Coins = require(game:GetService("ServerScriptService"):WaitForChild("Coins"))
-- товары: Tool с атрибутом Price
local items = RS:WaitForChild("ShopItems")
-- игрок просит купить
local buyItem = RS:WaitForChild("BuyItem")
-- покупка
buyItem.OnServerInvoke = function(player, itemName)
-- прислали не текст
if typeof(itemName) ~= "string" then return false, "Ошибка" end
-- товар
local item = items:FindFirstChild(itemName)
-- нет
if not item then return false, "Нет такого товара" end
-- остаётся ли после смерти
local keep = item:GetAttribute("KeepOnDeath")
-- навсегда купленное второй раз не продаём
if keep and player.StarterGear:FindFirstChild(itemName) then return false, "Уже куплено" end
-- списываем, если хватает
if not Coins.Spend(player, item:GetAttribute("Price") or 0) then return false, "Не хватает монет" end
-- товар — в рюкзак
item:Clone().Parent = player.Backpack
-- и в StarterGear — вернётся после смерти
if keep then item:Clone().Parent = player.StarterGear end
-- ответ
return true, "Куплено: " .. itemName
-- конец функции
endГде: StarterPlayer → StarterPlayerScripts · LocalScript
Зачем: Окно магазина и кнопки «Купить».
-- общее хранилище
local RS = game:GetService("ReplicatedStorage")
-- все надписи ProximityPrompt
local PPS = game:GetService("ProximityPromptService")
-- товары
local items = RS:WaitForChild("ShopItems")
-- купить
local buyItem = RS:WaitForChild("BuyItem")
-- этот игрок
local player = game.Players.LocalPlayer
-- окно магазина
local gui = player:WaitForChild("PlayerGui"):WaitForChild("ShopGui")
-- окно
local frame = gui:WaitForChild("Frame")
-- список товаров
local list = frame:WaitForChild("List")
-- строка ответа
local status = frame:WaitForChild("Status")
-- крестик
local closeButton = frame:WaitForChild("Close")
-- надпись в строке товара
local function Label(parent, text, x, width)
-- надпись
local label = Instance.new("TextLabel")
-- ширина
label.Size = UDim2.fromScale(width, 1)
-- место
label.Position = UDim2.fromScale(x, 0)
-- без фона
label.BackgroundTransparency = 1
-- по размеру
label.TextScaled = true
-- белый
label.TextColor3 = Color3.new(1, 1, 1)
-- жирный
label.Font = Enum.Font.GothamBold
-- текст
label.Text = text
-- в строку
label.Parent = parent
-- конец функции
end
-- собрать список товаров
local function Build()
-- старые строки
for _, child in ipairs(list:GetChildren()) do
-- убираем
if child:IsA("Frame") then child:Destroy() end
-- конец перебора
end
-- каждый товар
for i, item in ipairs(items:GetChildren()) do
-- строка
local row = Instance.new("Frame")
-- во всю ширину
row.Size = UDim2.new(1, -12, 0, 48)
-- фон
row.BackgroundColor3 = Color3.fromRGB(50, 50, 65)
-- порядок
row.LayoutOrder = i
-- в список
row.Parent = list
-- название
Label(row, item.Name, 0.02, 0.45)
-- цена
Label(row, (item:GetAttribute("Price") or 0) .. " монет", 0.48, 0.25)
-- кнопка
local buy = Instance.new("TextButton")
-- размер
buy.Size = UDim2.fromScale(0.22, 0.8)
-- справа
buy.Position = UDim2.fromScale(0.76, 0.1)
-- зелёная
buy.BackgroundColor3 = Color3.fromRGB(70, 170, 90)
-- белый текст
buy.TextColor3 = Color3.new(1, 1, 1)
-- по размеру
buy.TextScaled = true
-- жирный
buy.Font = Enum.Font.GothamBold
-- надпись
buy.Text = "Купить"
-- в строку
buy.Parent = row
-- нажали «Купить»
buy.MouseButton1Click:Connect(function()
-- просим сервер
local ok, message = buyItem:InvokeServer(item.Name)
-- ответ
status.Text = message
-- зелёный или красный
status.TextColor3 = ok and Color3.fromRGB(90, 230, 120) or Color3.fromRGB(240, 80, 80)
-- конец обработчика
end)
-- конец перебора
end
-- конец функции
end
-- нажал E у надписи
PPS.PromptTriggered:Connect(function(prompt)
-- это не магазин
if prompt.Name ~= "ShopPrompt" then return end
-- свежий список
Build()
-- ответа пока нет
status.Text = ""
-- открываем
frame.Visible = true
-- конец обработчика
end)
-- крестик
closeButton.MouseButton1Click:Connect(function()
-- закрываем
frame.Visible = false
-- конец обработчика
end)Запусти Play (или Run) и убедись: