Roblox · Приключение · урок 5
Торговец открывает окно магазина, игрок покупает зелья за монеты. Цены проверяет сервер.
Синим — что добавляем на этом уроке.
ReplicatedStorage └─ Events (Folder) ├─ ShopEvent (RemoteEvent) └─ BuyFunction (RemoteFunction) ServerStorage └─ Shop (Folder) └─ HealingPotion, InvisiblePotion (Tool) — внутри IntValue Price ServerScriptService └─ BuyScript (Script) Workspace └─ Trader (Model) — Head → ProximityPrompt «Торговать» └─ TraderScript (Script) StarterGui └─ ShopGui (ScreenGui) — ResetOnSpawn выкл. ├─ ShopFrame (Frame) — Visible выкл. │ ├─ Items (Frame) — UIListLayout + кнопки «HealingPotion», «InvisiblePotion» │ ├─ Message (TextLabel) │ └─ CloseButton (TextButton) └─ ShopLocal (LocalScript)
Где: Workspace → Trader · Script
Зачем: Открывает магазин.
-- общее хранилище
local RS = game:GetService("ReplicatedStorage")
-- открыть магазин
local shopEvent = RS:WaitForChild("Events"):WaitForChild("ShopEvent")
-- «Торговать»
local prompt = script.Parent:WaitForChild("Head"):WaitForChild("ProximityPrompt")
-- игрок нажал E
prompt.Triggered:Connect(function(player)
-- только у него откроется окно
shopEvent:FireClient(player)
-- конец функции
end)Где: StarterGui → ShopGui · LocalScript
Зачем: Окно магазина.
-- общее хранилище
local RS = game:GetService("ReplicatedStorage")
-- события
local events = RS:WaitForChild("Events")
-- открыть
local shopEvent = events:WaitForChild("ShopEvent")
-- купить и получить ответ
local buyFunction = events:WaitForChild("BuyFunction")
-- окно
local frame = script.Parent:WaitForChild("ShopFrame")
-- ответ магазина
local message = frame:WaitForChild("Message")
-- торговец позвал
shopEvent.OnClientEvent:Connect(function()
-- без старых сообщений
message.Text = ""
-- открываем
frame.Visible = true
-- конец функции
end)
-- «Закрыть» — подписываемся один раз
frame:WaitForChild("CloseButton").MouseButton1Click:Connect(function()
-- закрываем
frame.Visible = false
-- конец функции
end)
-- кнопки товаров
for _, button in ipairs(frame:WaitForChild("Items"):GetChildren()) do
-- только кнопки
if button:IsA("TextButton") then
-- нажатие
button.MouseButton1Click:Connect(function()
-- имя кнопки = имя товара; ждём ответ
local _, text = buyFunction:InvokeServer(button.Name)
-- «Куплено» или «Не хватает монет»
message.Text = text
-- конец функции
end)
-- конец проверки
end
-- конец перебора
endГде: ServerScriptService · Script
Зачем: Покупка с проверкой.
-- общее хранилище
local RS = game:GetService("ReplicatedStorage")
-- товары лежат здесь — клиент их не видит и не подменит
local SS = game:GetService("ServerStorage")
-- покупка
local buyFunction = RS:WaitForChild("Events"):WaitForChild("BuyFunction")
-- товары
local shop = SS:WaitForChild("Shop")
-- клиент хочет купить
buyFunction.OnServerInvoke = function(player, itemName)
-- пришло не имя
if typeof(itemName) ~= "string" then return false, "Ошибка" end
-- товар
local item = shop:FindFirstChild(itemName)
-- его цена
local price = item and item:FindFirstChild("Price")
-- монеты игрока
local stats = player:FindFirstChild("leaderstats")
-- рюкзак
local backpack = player:FindFirstChild("Backpack")
-- что-то не так
if not price or not stats or not backpack then return false, "Такого товара нет" end
-- денег мало
if stats.Coins.Value < price.Value then
-- ответ
return false, "Не хватает монет: нужно " .. price.Value
-- конец проверки
end
-- списываем
stats.Coins.Value -= price.Value
-- товар в рюкзак
item:Clone().Parent = backpack
-- ответ
return true, "Куплено!"
-- конец функции
endЗапусти Play (или Run) и убедись: