Roblox · Захват флага · урок 4
Один серверный скрипт управляет всеми флагами: схватил чужой — он за спиной; донёс до своей базы — очко команде; погиб — флаг вернулся домой.
Синим — что добавляем на этом уроке.
Workspace └─ Bases (Folder) ServerScriptService └─ FlagServer (Script) Players → игрок — создаёт скрипт └─ leaderstats (Folder) └─ Flags (IntValue) — принесённые флаги
Где: ServerScriptService · Script
Зачем: Захват, перенос, возврат флагов и очки.
-- игроки
local Players = game:GetService("Players")
-- команды
local Teams = game:GetService("Teams")
-- базы; имя базы = имя команды
local bases = workspace:WaitForChild("Bases")
-- имя базы → функция «вернуть её флаг»
local returns = {}
-- игрок зашёл
Players.PlayerAdded:Connect(function(player)
-- таблица по Tab
local leaderstats = Instance.new("Folder")
-- имя строго такое
leaderstats.Name = "leaderstats"
-- в игрока
leaderstats.Parent = player
-- принесённые флаги
local flags = Instance.new("IntValue")
-- столбец
flags.Name = "Flags"
-- в таблицу
flags.Parent = leaderstats
-- конец функции
end)
-- живой игрок, чья деталь коснулась
local function GetPlayer(hit)
-- модель персонажа
local character = hit.Parent
-- Humanoid
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
-- не персонаж или погиб
if not humanoid or humanoid.Health <= 0 then return nil end
-- игрок
return Players:GetPlayerFromCharacter(character)
-- конец функции
end
-- настраиваем одну базу
local function Setup(base)
-- команда этой базы
local team = Teams:WaitForChild(base.Name)
-- модель флага
local flag = base:WaitForChild("Flag")
-- главная деталь флага
local hitbox = flag:WaitForChild("Hitbox")
-- куда приносить чужой флаг
local givePart = base:WaitForChild("GivePart")
-- место флага на подставке
local home = hitbox.CFrame
-- кто несёт флаг
local carrier = nil
-- подписки на смерть носителя
local connections = {}
-- флаг — обратно на подставку
local function ReturnFlag()
-- отписываемся
for _, connection in ipairs(connections) do connection:Disconnect() end
-- список пуст
table.clear(connections)
-- у игрока больше нет флага
if carrier then carrier:SetAttribute("HasFlag", nil) end
-- никто не несёт
carrier = nil
-- сварка со спиной
local weld = hitbox:FindFirstChild("CarryWeld")
-- убираем
if weld then weld:Destroy() end
-- закрепляем
hitbox.Anchored = true
-- на подставку
hitbox.CFrame = home
-- конец функции
end
-- чтобы другая база могла вернуть этот флаг
returns[base.Name] = ReturnFlag
-- кто-то коснулся флага
hitbox.Touched:Connect(function(hit)
-- флаг уже несут
if carrier then return end
-- игрок
local player = GetPlayer(hit)
-- свой флаг не берут
if not player or not player.Team or player.Team == team then return end
-- два флага сразу нельзя
if player:GetAttribute("HasFlag") then return end
-- Humanoid носителя
local humanoid = player.Character:FindFirstChildOfClass("Humanoid")
-- к нему крепим
local root = player.Character:FindFirstChild("HumanoidRootPart")
-- персонаж не собран
if not root then return end
-- запоминаем носителя
carrier = player
-- чей флаг у игрока
player:SetAttribute("HasFlag", base.Name)
-- сварка со смещением
local weld = Instance.new("Weld")
-- имя — чтобы найти и убрать
weld.Name = "CarryWeld"
-- спина игрока
weld.Part0 = root
-- флаг
weld.Part1 = hitbox
-- чуть выше и за спиной
weld.C0 = CFrame.new(0, 1.5, 1.2)
-- в флаг
weld.Parent = hitbox
-- флаг едет за игроком
hitbox.Anchored = false
-- погиб — флаг домой
table.insert(connections, humanoid.Died:Connect(ReturnFlag))
-- вышел или возродился — тоже
table.insert(connections, player.CharacterRemoving:Connect(ReturnFlag))
-- конец функции
end)
-- кто-то пришёл на свою базу
givePart.Touched:Connect(function(hit)
-- игрок
local player = GetPlayer(hit)
-- только игроки этой команды
if not player or player.Team ~= team then return end
-- чей флаг принёс
local enemyName = player:GetAttribute("HasFlag")
-- ничего не несёт
if not enemyName or not returns[enemyName] then return end
-- чужой флаг возвращается на свою подставку
returns[enemyName]()
-- таблица игрока
local stats = player:FindFirstChild("leaderstats")
-- +1 флаг
if stats then stats.Flags.Value += 1 end
-- конец функции
end)
-- конец функции
end
-- все базы
for _, base in ipairs(bases:GetChildren()) do
-- настраиваем
task.spawn(Setup, base)
-- конец перебора
endЗапусти Play (или Run) и убедись: