Roblox · Шутер · урок 3

Выстрел: клиент и сервер

Клиент (LocalScript) знает, куда навёл мышь игрок, и сообщает это серверу через RemoteEvent. Сервер (Script) создаёт пулю — её видят все.

Структура

Синим — что добавляем на этом уроке.

Workspace
└─ Gun (Tool)
   ├─ Handle (Part)
   │  └─ Shoot (Sound) — звук выстрела
   ├─ Shot (RemoteEvent) — клиент → сервер
   ├─ GunLocal (LocalScript)
   └─ GunServer (Script)

Шаги

  1. Звук: Toolbox → Audio → «Gun Shot» → в Handle, имя Shoot.
  2. Клиент — ввод, интерфейс, камера. Сервер — всё, что должны видеть все и что нельзя подделать.
  3. Tool.Activated — клик (или тап на телефоне), пока оружие в руках.

Скрипты

GunLocal

Где: Workspace → Gun · LocalScript
Зачем: По клику отправляет на сервер точку под курсором.

-- оружие (Tool)
local gun = script.Parent
-- сигнал «выстрел» на сервер
local shotEvent = gun:WaitForChild("Shot")
-- этот игрок
local player = game.Players.LocalPlayer
-- его мышь: mouse.Hit — точка под курсором
local mouse = player:GetMouse()
-- оружие в руках?
local equipped = false

-- взяли оружие в руки
local function OnEquipped()
    -- запоминаем
    equipped = true
-- конец функции
end
-- каждый раз, когда берут в руки
gun.Equipped:Connect(OnEquipped)
-- подобрали с земли: скрипт запустился, когда оружие уже в руках, — Equipped был раньше
if gun.Parent and gun.Parent:FindFirstChildOfClass("Humanoid") then OnEquipped() end

-- убрали оружие
gun.Unequipped:Connect(function()
    -- запоминаем
    equipped = false
-- конец обработчика
end)

-- клик, пока оружие в руках
gun.Activated:Connect(function()
    -- просим сервер выстрелить в точку под курсором
    shotEvent:FireServer(mouse.Hit.Position)
-- конец обработчика
end)

GunServer

Где: Workspace → Gun · Script
Зачем: Создаёт пулю, разгоняет её к цели, играет звук.

-- оружие (Tool)
local gun = script.Parent
-- модель оружия
local handle = gun:WaitForChild("Handle")
-- сигнал «выстрел» от клиента
local shotEvent = gun:WaitForChild("Shot")
-- звук выстрела
local shootSound = handle:WaitForChild("Shoot")
-- удаление по таймеру
local Debris = game:GetService("Debris")
-- скорость пули
local bulletSpeed = 500

-- клиент сообщил о выстреле и точке под курсором
shotEvent.OnServerEvent:Connect(function(player, mousePosition)
    -- стреляет только тот, у кого оружие в руках
    if gun.Parent ~= player.Character then return end
    -- новая пуля
    local bullet = Instance.new("Part")
    -- шарик
    bullet.Shape = Enum.PartType.Ball
    -- маленький
    bullet.Size = Vector3.new(0.3, 0.3, 0.3)
    -- чёрный
    bullet.BrickColor = BrickColor.new("Black")
    -- не отскакивает от своего же оружия
    bullet.CanCollide = false
    -- у ствола, смотрит на курсор
    bullet.CFrame = CFrame.new(handle.Position, mousePosition)
    -- в мир
    bullet.Parent = workspace
    -- физику пули считает сервер — попадания честные
    bullet:SetNetworkOwner(nil)
    -- летит вперёд
    bullet.AssemblyLinearVelocity = bullet.CFrame.LookVector * bulletSpeed
    -- звук выстрела
    shootSound:Play()
    -- промах — пуля удалится через 10 секунд
    Debris:AddItem(bullet, 10)
-- конец обработчика
end)

Проверка

Запусти Play (или Run) и убедись: