Roblox · RPG · урок 12
Финал: главное меню на фоне карты, сохранение монет, уровня, опыта и класса, звуки локаций — и публикация.
Синим — что добавляем на этом уроке.
Workspace ├─ CameraPart (Part) — невидимый, ракурс меню └─ MapFolder → Sound (Part) — Sound: Playing, Looped ServerScriptService └─ PlayerData (Script) — + сохранение StarterGui └─ MainMenuGui (ScreenGui) — ResetOnSpawn выкл., DisplayOrder 10 ├─ Background (ImageLabel) — узор фона ├─ BackFrame (Frame) — RPG (название), Logo, PlayButton └─ MainMenu (LocalScript)
Где: StarterGui → MainMenuGui · LocalScript
Зачем: Главное меню.
-- игроки
local Players = game:GetService("Players")
-- каждый кадр
local RunService = game:GetService("RunService")
-- этот игрок
local player = Players.LocalPlayer
-- камера
local camera = workspace.CurrentCamera
-- MainMenuGui
local gui = script.Parent
-- «Играть»
local playButton = gui:WaitForChild("BackFrame"):WaitForChild("PlayButton")
-- откуда смотрит камера меню
local cameraPart = workspace:WaitForChild("CameraPart")
-- управление персонажем
local controls = require(player:WaitForChild("PlayerScripts"):WaitForChild("PlayerModule")):GetControls()
-- в меню персонаж не ходит
controls:Disable()
-- каждый кадр, пока меню
local follow = RunService.RenderStepped:Connect(function()
-- камерой управляет скрипт
camera.CameraType = Enum.CameraType.Scriptable
-- красивый вид на карту
camera.CFrame = cameraPart.CFrame
-- конец функции
end)
-- «Играть»
playButton.MouseButton1Click:Connect(function()
-- камера свободна
follow:Disconnect()
-- обычная камера за персонажем
camera.CameraType = Enum.CameraType.Custom
-- можно ходить
controls:Enable()
-- меню прячется (ResetOnSpawn выкл. — после смерти не вернётся)
gui.Enabled = false
-- конец функции
end)Где: ServerScriptService · Script
Зачем: Данные игрока и сохранение.
-- игроки
local Players = game:GetService("Players")
-- сохранение
local DSS = game:GetService("DataStoreService")
-- хранилище RPG
local store = DSS:GetDataStore("RPGData")
-- у кого данные загрузились
local loaded = {}
-- создаёт контейнер со значением
local function Value(class, name, value, parent)
-- контейнер
local v = Instance.new(class)
-- имя
v.Name = name
-- значение
v.Value = value
-- на место
v.Parent = parent
-- отдаём
return v
-- конец функции
end
-- игрок зашёл
local function Setup(player)
-- таблица по Tab
local leaderstats = Instance.new("Folder")
-- имя строго такое
leaderstats.Name = "leaderstats"
-- в игрока
leaderstats.Parent = player
-- кошелёк
local coins = Value("IntValue", "Монеты", 0, leaderstats)
-- уровень
local lvl = Value("IntValue", "Lvl", 1, player)
-- опыт
local exp = Value("IntValue", "Exp", 0, player)
-- сколько опыта до следующего уровня
local required = Value("IntValue", "RequiredExp", 100, player)
-- загружаем сохранение
local ok, data = pcall(function() return store:GetAsync("rpg_" .. player.UserId) end)
-- загрузка удалась
if ok then
-- сохранение есть
if type(data) == "table" then
-- монеты
coins.Value = data.Coins or 0
-- уровень
lvl.Value = data.Lvl or 1
-- порог уровня
required.Value = lvl.Value * 100
-- опыт
exp.Value = data.Exp or 0
-- класс — ClassServer выдаст навыки и оружие
if data.Class then player:SetAttribute("Class", data.Class) end
-- конец проверки
end
-- можно сохранять
loaded[player] = true
-- конец проверки
end
-- опыт изменился
exp.Changed:Connect(function()
-- хватает на уровень (и даже на несколько)
while exp.Value >= required.Value do
-- лишний опыт не пропадает
exp.Value -= required.Value
-- новый уровень
lvl.Value += 1
-- следующий порог выше
required.Value = lvl.Value * 100
-- конец цикла
end
-- конец функции
end)
-- конец функции
end
-- сохранить игрока
local function Save(player)
-- не загрузились — не затираем сохранение нулями
if not loaded[player] then return end
-- что сохраняем
local data = {
-- монеты
Coins = player.leaderstats["Монеты"].Value,
-- уровень
Lvl = player.Lvl.Value,
-- опыт
Exp = player.Exp.Value,
-- класс
Class = player:GetAttribute("Class"),
-- конец таблицы
}
-- записываем
pcall(function() store:SetAsync("rpg_" .. player.UserId, data) end)
-- конец функции
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)Запусти Play (или Run) и убедись: