Roblox · Сбор-а-тон · урок 2
Прячем предметы и учим игру засчитывать находки: клик по предмету — сообщение «Найдено!», и находка сохраняется.
Синим — что добавляем на этом уроке.
Workspace └─ Items (Folder) └─ Красный кристалл (Part) — имя = название предмета ├─ Decal (Decal) — картинка для журнала ├─ Difficulty (StringValue) — Easy, Medium или Hard ├─ Description (StringValue) — описание └─ BadgeID (NumberValue) — 0 или ID нашивки ReplicatedStorage └─ Events (Folder) └─ CollectEvent (RemoteEvent) ServerScriptService └─ CollectServer (Script) StarterGui └─ CollectGui (ScreenGui) — ResetOnSpawn выкл. ├─ Message (TextLabel) — Visible выкл. ├─ Found (Sound) └─ CollectLocal (LocalScript)
Где: ServerScriptService · Script
Зачем: Клики, находки, сохранение.
-- игроки
local Players = game:GetService("Players")
-- общее хранилище
local RS = game:GetService("ReplicatedStorage")
-- сохранение
local DSS = game:GetService("DataStoreService")
-- нашивки (по желанию)
local BadgeService = game:GetService("BadgeService")
-- все предметы
local items = workspace:WaitForChild("Items")
-- события
local events = RS:WaitForChild("Events")
-- «нашёл предмет»
local collectEvent = events:WaitForChild("CollectEvent")
-- хранилище находок
local store = DSS:GetDataStore("CollectData")
-- у кого находки загрузились
local loaded = {}
-- сохранить находки
local function Save(player)
-- не загрузились — не затираем
if not loaded[player] then return end
-- имена найденных
local list = {}
-- каждая находка
for _, mark in ipairs(player.Found:GetChildren()) do
-- в список
table.insert(list, mark.Name)
-- конец перебора
end
-- сохраняем
pcall(function() store:SetAsync("found_" .. player.UserId, list) end)
-- конец функции
end
-- игрок нашёл предмет
local function Collect(player, item)
-- его находки
local found = player:FindFirstChild("Found")
-- уже нашёл
if not found or found:FindFirstChild(item.Name) then return end
-- отметка
local mark = Instance.new("BoolValue")
-- имя = предмет
mark.Name = item.Name
-- в папку игрока
mark.Parent = found
-- сообщение на экране
collectEvent:FireClient(player, item.Name)
-- ID нашивки
local badge = item:FindFirstChild("BadgeID")
-- нашивка настроена
if badge and badge.Value > 0 then
-- не задерживаем остальное
task.spawn(function()
-- выдаём; в Studio может не сработать
pcall(function() BadgeService:AwardBadge(player.UserId, badge.Value) end)
-- конец функции
end)
-- конец проверки
end
-- конец функции
end
-- игрок зашёл
local function Setup(player)
-- его находки
local found = Instance.new("Folder")
-- имя
found.Name = "Found"
-- загружаем
local ok, list = pcall(function() return store:GetAsync("found_" .. player.UserId) end)
-- загрузка удалась
if ok then
-- каждое сохранённое имя
for _, name in ipairs(list or {}) do
-- такой предмет ещё есть
if items:FindFirstChild(name) then
-- отметка
local mark = Instance.new("BoolValue")
-- имя
mark.Name = name
-- в папку
mark.Parent = found
-- конец проверки
end
-- конец перебора
end
-- можно сохранять
loaded[player] = true
-- конец проверки
end
-- в игрока — клиент видит
found.Parent = player
-- конец функции
end
-- новые игроки
Players.PlayerAdded:Connect(Setup)
-- кто зашёл раньше скрипта
for _, player in ipairs(Players:GetPlayers()) do task.spawn(Setup, player) end
-- игрок вышел
Players.PlayerRemoving:Connect(function(player)
-- сохраняем
Save(player)
-- забываем
loaded[player] = nil
-- конец функции
end)
-- сервер закрывается
game:BindToClose(function()
-- сохраняем всех
for _, player in ipairs(Players:GetPlayers()) do Save(player) end
-- конец функции
end)
-- каждый предмет — один раз
for _, item in ipairs(items:GetChildren()) do
-- клик
local clicker = item:FindFirstChildOfClass("ClickDetector") or Instance.new("ClickDetector")
-- кликнуть можно только рядом
clicker.MaxActivationDistance = 20
-- в предмет
clicker.Parent = item
-- кто-то кликнул
clicker.MouseClick:Connect(function(player)
-- засчитываем
Collect(player, item)
-- конец функции
end)
-- конец перебора
endГде: StarterGui → CollectGui · LocalScript
Зачем: Сообщение о находке.
-- общее хранилище
local RS = game:GetService("ReplicatedStorage")
-- «нашёл предмет»
local collectEvent = RS:WaitForChild("Events"):WaitForChild("CollectEvent")
-- CollectGui
local gui = script.Parent
-- надпись
local message = gui:WaitForChild("Message")
-- звук находки
local sound = gui:WaitForChild("Found")
-- номер последнего сообщения
local shown = 0
-- сервер засчитал находку
collectEvent.OnClientEvent:Connect(function(name)
-- новое сообщение
shown += 1
-- его номер
local my = shown
-- текст
message.Text = "Найдено: " .. name .. "!"
-- показываем
message.Visible = true
-- звук
sound:Play()
-- ждём
task.wait(2.5)
-- прячем, если не пришло новое
if shown == my then message.Visible = false end
-- конец функции
end)Запусти Play (или Run) и убедись: