Roblox · Королевская битва · урок 10
Погиб — мир размывается, появляется экран смерти с отсчётом и кнопкой «В лобби». Там, где погиб, остаются его предметы и шар здоровья.
Синим — что добавляем на этом уроке.
Players — CharacterAutoLoads выкл. (ставит DeathServer) StarterGui └─ DeathGui (ScreenGui) — ResetOnSpawn выкл. └─ DeathFrame (Frame) — Visible выкл.; UIAspectRatioConstraint ├─ Skull (ImageLabel) ├─ TeleportButton (TextButton) — «В лобби» ├─ TimeToTeleport (TextLabel) └─ DeathLocal (LocalScript) ReplicatedStorage └─ DeathEvent (RemoteEvent) ServerStorage └─ HealthDrop (Part) — зелёный шар; Sound ServerScriptService ├─ DeathServer (Script) └─ DropServer (Script)
Где: ServerScriptService · Script
Зачем: Возрождение.
-- игроки
local Players = game:GetService("Players")
-- события
local RS = game:GetService("ReplicatedStorage")
-- кнопка «В лобби»
local deathEvent = RS:WaitForChild("DeathEvent")
-- столько же, сколько отсчёт на экране смерти
local RESPAWN_TIME = 8
-- сами решаем, когда игрок возрождается
Players.CharacterAutoLoads = false
-- игрок мёртв?
local function IsDead(player)
-- Humanoid
local humanoid = player.Character and player.Character:FindFirstChildOfClass("Humanoid")
-- нет персонажа или здоровье 0
return not humanoid or humanoid.Health <= 0
-- конец функции
end
-- возродить в лобби
local function Respawn(player)
-- только мёртвых — живой не «перезапустится» кнопкой
if player.Parent and IsDead(player) then player:LoadCharacter() end
-- конец функции
end
-- игрок зашёл
local function Setup(player)
-- новый персонаж
player.CharacterAdded:Connect(function(character)
-- погиб
character:WaitForChild("Humanoid").Died:Connect(function()
-- страховка: если клиент не нажал — возродим сами
task.delay(RESPAWN_TIME + 2, Respawn, player)
-- конец функции
end)
-- конец функции
end)
-- первый персонаж — сами (автозагрузка выключена)
if not player.Character then player:LoadCharacter() end
-- конец функции
end
-- новые игроки
Players.PlayerAdded:Connect(Setup)
-- кто зашёл раньше скрипта
for _, player in ipairs(Players:GetPlayers()) do task.spawn(Setup, player) end
-- нажал «В лобби» или кончился отсчёт
deathEvent.OnServerEvent:Connect(Respawn)Где: StarterGui → DeathGui → DeathFrame · LocalScript
Зачем: Экран смерти.
-- игроки
local Players = game:GetService("Players")
-- события
local RS = game:GetService("ReplicatedStorage")
-- плавность
local TS = game:GetService("TweenService")
-- размытие
local Lighting = game:GetService("Lighting")
-- этот игрок
local player = Players.LocalPlayer
-- DeathFrame
local frame = script.Parent
-- «В лобби»
local button = frame:WaitForChild("TeleportButton")
-- отсчёт
local timeLabel = frame:WaitForChild("TimeToTeleport")
-- попросить возрождение
local deathEvent = RS:WaitForChild("DeathEvent")
-- секунд до автоматического возвращения
local RESPAWN_TIME = 8
-- размытие мира
local blur = Lighting:FindFirstChild("DeathScreenBlur") or Instance.new("BlurEffect")
-- имя
blur.Name = "DeathScreenBlur"
-- пока не размыто
blur.Size = 0
-- включено (сила 0)
blur.Parent = Lighting
-- плавно
local info = TweenInfo.new(1, Enum.EasingStyle.Quint, Enum.EasingDirection.InOut)
-- сейчас мёртв?
local dead = false
-- экран смерти скрыт
frame.Visible = false
-- в лобби
local function Leave()
-- уже
if not dead then return end
-- больше не ждём
dead = false
-- прячем экран
frame.Visible = false
-- мир снова чёткий
TS:Create(blur, info, {Size = 0}):Play()
-- сервер возрождает
deathEvent:FireServer()
-- конец функции
end
-- подписка одна (в методичке — при каждой смерти)
button.MouseButton1Click:Connect(Leave)
-- новый персонаж
local function OnCharacter(character)
-- Humanoid
local humanoid = character:WaitForChild("Humanoid")
-- жив
dead = false
-- экран скрыт
frame.Visible = false
-- без размытия
blur.Size = 0
-- погиб
humanoid.Died:Connect(function()
-- мёртв
dead = true
-- мир размывается
TS:Create(blur, info, {Size = 20}):Play()
-- секунда
task.wait(1)
-- уже нажал
if not dead then return end
-- экран смерти
frame.Visible = true
-- отсчёт
for i = RESPAWN_TIME, 1, -1 do
-- нажал кнопку
if not dead then return end
-- текст
timeLabel.Text = "В лобби через " .. i .. " с"
-- секунда
task.wait(1)
-- конец отсчёта
end
-- время вышло
Leave()
-- конец функции
end)
-- конец функции
end
-- каждый новый персонаж
player.CharacterAdded:Connect(OnCharacter)
-- текущий
if player.Character then OnCharacter(player.Character) endГде: ServerScriptService · Script
Зачем: Лут погибшего и шар здоровья.
-- игроки
local Players = game:GetService("Players")
-- образец дропа
local SS = game:GetService("ServerStorage")
-- удаление через время
local Debris = game:GetService("Debris")
-- шар здоровья (внутри Sound)
local healthSample = SS:WaitForChild("HealthDrop")
-- сколько лечит
local HEAL = 40
-- через сколько секунд исчезнет, если не взяли
local LIFETIME = 120
-- шар здоровья на месте смерти
local function DropHealth(position)
-- копия
local orb = healthSample:Clone()
-- висит
orb.Anchored = true
-- сквозь
orb.CanCollide = false
-- где погиб
orb.Position = position
-- в мир
orb.Parent = workspace
-- ещё не взяли
local used = false
-- коснулись
orb.Touched:Connect(function(hit)
-- персонаж
local humanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
-- уже взяли или мёртв
if used or not humanoid or humanoid.Health <= 0 then return end
-- один раз (в методичке лечил, пока играл звук)
used = true
-- лечим
humanoid.Health = math.min(humanoid.Health + HEAL, humanoid.MaxHealth)
-- звук
orb.Sound:Play()
-- шар исчезает
orb.Transparency = 1
-- удалим, когда доиграет звук
Debris:AddItem(orb, 2)
-- конец функции
end)
-- не взяли — исчезнет сам
Debris:AddItem(orb, LIFETIME)
-- конец функции
end
-- предметы погибшего — на землю
local function DropTools(player, character, position)
-- список
local tools = {}
-- рюкзак
for _, tool in ipairs(player.Backpack:GetChildren()) do
-- инструменты
if tool:IsA("Tool") then table.insert(tools, tool) end
-- конец перебора
end
-- что было в руках
local held = character:FindFirstChildOfClass("Tool")
-- тоже
if held then table.insert(tools, held) end
-- каждый
for i, tool in ipairs(tools) do
-- за что двигать
local handle = tool:FindFirstChild("Handle")
-- есть
if handle then
-- раскладываем по кругу
local angle = i / #tools * math.pi * 2
-- на землю
tool.Parent = workspace:FindFirstChild("Loot") or workspace
-- вокруг места смерти
handle.CFrame = CFrame.new(position + Vector3.new(math.cos(angle) * 4, 1, math.sin(angle) * 4))
-- конец проверки
end
-- конец перебора
end
-- конец функции
end
-- игрок зашёл
local function Setup(player)
-- новый персонаж
player.CharacterAdded:Connect(function(character)
-- погиб
character:WaitForChild("Humanoid").Died:Connect(function()
-- центр
local root = character:FindFirstChild("HumanoidRootPart")
-- уже нет
if not root then return end
-- место смерти
local position = root.Position
-- лут погибшего
DropTools(player, character, position)
-- секунда
task.wait(1)
-- шар здоровья
DropHealth(position)
-- конец функции
end)
-- конец функции
end)
-- конец функции
end
-- новые игроки
Players.PlayerAdded:Connect(Setup)
-- кто зашёл раньше скрипта
for _, player in ipairs(Players:GetPlayers()) do Setup(player) endЗапусти Play (или Run) и убедись: