Roblox · RPG · урок 6

Мечник: меч и кувырок

Классовое оружие мечника — меч с анимацией удара и звуками, и навык кувырок на E. Чужой класс меч в руки взять может, но ударить — нет.

Структура

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

ServerStorage
├─ Weapons (Folder)
│  └─ Sword (Tool)
│     ├─ Handle (Part) — невидимая коробка вокруг меча, CanCollide выкл.
│     │  └─ WeldConstraint (WeldConstraint) — Part0 Handle, Part1 Blade
│     ├─ Blade (Part) — видимый меч
│     ├─ YouAreNotGui (ScreenGui) — Frame → TextLabel «Ты не мечник»
│     └─ SwordScript (Script)
│        ├─ Animation (Animation) — удар, приоритет Action
│        └─ Swing, Hit (Sound)
└─ Classes → Swordsman (Folder)
   └─ Dash (LocalScript)
      └─ Animation (Animation) — кувырок, приоритет Core

Шаги

  1. Модель меча — одна деталь (Union) или несколько; видимая часть — «Blade». Вокруг — невидимая коробка «Handle» (Transparency 1, CanCollide выкл.): за неё держит персонаж, ею же и бьём.
  2. Tool «Sword», внутрь Handle и Blade. Сварка WeldConstraint: сначала клик по Handle, потом по Blade — Handle главный. Хват — плагин Tool Grip Editor.
  3. Анимация удара: Rig Builder + Animation Editor, приоритет Action (⋯ → Set Animation Priority), Publish, ID — в Animation внутри SwordScript.
  4. Приоритеты сверху вниз: Action4…Action, Movement, Idle, Core. Высокий перебивает низкий: удар поверх ходьбы.
  5. Звуки Swing и Hit (Toolbox: Sword Swing, Sword Hit) — внутрь SwordScript.
  6. YouAreNotGui: ScreenGui → Frame → TextLabel «Ты не мечник». Перенеси его в Sword.
  7. Меч бьёт только мобов (игроков — нет), каждого один раз за взмах, и ставит метку «кто ударил» — за победу дадут опыт.
  8. Готовый Sword — в ServerStorage → Weapons: ClassServer выдаст его мечнику.
  9. Кувырок: анимация (приоритет Core), LocalScript «Dash» с Animation в папке Classes → Swordsman. E — рывок на полсекунды, потом прежняя скорость (а не 16, как в методичке).

Скрипты

SwordScript

Где: ServerStorage → Weapons → Sword · Script
Зачем: Удар мечом.

-- игроки
local Players = game:GetService("Players")
-- удаляет метки через время
local Debris = game:GetService("Debris")
-- меч
local tool = script.Parent
-- невидимая коробка вокруг меча — ею и бьём
local handle = tool:WaitForChild("Handle")
-- анимация удара
local anim = script:WaitForChild("Animation")
-- звук взмаха
local swingSound = script:WaitForChild("Swing")
-- звук попадания
local hitSound = script:WaitForChild("Hit")
-- «Ты не мечник»
local notGui = tool:WaitForChild("YouAreNotGui")
-- чей это меч
local CLASS = "Swordsman"
-- длина взмаха
local COOLDOWN = 0.6
-- урон за удар
local DAMAGE = 15
-- идёт взмах
local swinging = false
-- кого уже ударили этим взмахом
local hitList = {}

-- клик с мечом в руках
tool.Activated:Connect(function()
    -- хозяин
    local player = Players:GetPlayerFromCharacter(tool.Parent)
    -- его Humanoid
    local humanoid = tool.Parent:FindFirstChildOfClass("Humanoid")
    -- нет хозяина, погиб или взмах идёт
    if not player or not humanoid or humanoid.Health <= 0 or swinging then return end
    -- чужой класс
    if player:GetAttribute("Class") ~= CLASS then
        -- надпись ещё не показана
        if notGui.Parent == tool then
            -- «Ты не …» на экран
            notGui.Parent = player.PlayerGui
            -- 2 секунды
            task.wait(2)
            -- прячем обратно в оружие
            notGui.Parent = tool
        -- конец проверки
        end
        -- не бьём
        return
    -- конец проверки
    end
    -- начали
    swinging = true
    -- новый взмах — список пуст
    table.clear(hitList)
    -- анимация удара
    if anim.AnimationId ~= "" then humanoid:FindFirstChildOfClass("Animator"):LoadAnimation(anim):Play() end
    -- вжух
    swingSound:Play()
    -- ждём
    task.wait(COOLDOWN)
    -- можно снова
    swinging = false
-- конец функции
end)

-- меч коснулся чего-то
handle.Touched:Connect(function(hit)
    -- бьём только во время взмаха
    if not swinging then return end
    -- хозяин
    local player = Players:GetPlayerFromCharacter(tool.Parent)
    -- чья деталь
    local model = hit:FindFirstAncestorOfClass("Model")
    -- её Humanoid
    local target = model and model:FindFirstChildOfClass("Humanoid")
    -- не цель, сам себя или уже ударили
    if not player or not target or model == tool.Parent or target.Health <= 0 or hitList[target] then return end
    -- игроков не бьём — только мобов
    if Players:GetPlayerFromCharacter(model) then return end
    -- этим взмахом больше не бьём
    hitList[target] = true
    -- прошлая метка «кто ударил»
    local old = target:FindFirstChild("creator")
    -- убираем
    if old then old:Destroy() end
    -- новая метка
    local tag = Instance.new("ObjectValue")
    -- стандартное имя метки в Roblox
    tag.Name = "creator"
    -- кто ударил — получит опыт за победу
    tag.Value = player
    -- в Humanoid цели
    tag.Parent = target
    -- через 3 секунды метка исчезнет
    Debris:AddItem(tag, 3)
    -- урон
    local damage = DAMAGE
    -- бьём
    target:TakeDamage(damage)
    -- звук попадания
    hitSound:Play()
-- конец функции
end)

Dash

Где: ServerStorage → Classes → Swordsman · LocalScript
Зачем: Кувырок на E.

-- клавиатура
local UIS = game:GetService("UserInputService")
-- игроки
local Players = game:GetService("Players")
-- персонаж: Dash → Swordsman → персонаж
local character = script.Parent.Parent
-- Humanoid
local humanoid = character:WaitForChild("Humanoid")
-- анимация кувырка
local anim = script:WaitForChild("Animation")
-- навык класса — на E
local KEY = Enum.KeyCode.E
-- перезарядка
local COOLDOWN = 3
-- скорость во время кувырка
local DASH_SPEED = 45
-- можно использовать
local ready = true

-- нажали клавишу
UIS.InputBegan:Connect(function(input, processed)
    -- не та клавиша, перезарядка или погиб
    if processed or input.KeyCode ~= KEY or not ready or humanoid.Health <= 0 then return end
    -- перезарядка началась
    ready = false
    -- кувырок
    if anim.AnimationId ~= "" then humanoid:FindFirstChildOfClass("Animator"):LoadAnimation(anim):Play() end
    -- скорость до кувырка (вдруг на игроке нимб)
    local old = humanoid.WalkSpeed
    -- рывок
    humanoid.WalkSpeed = DASH_SPEED
    -- полсекунды
    task.wait(0.5)
    -- прежняя скорость
    humanoid.WalkSpeed = old
    -- перезарядка
    task.wait(COOLDOWN)
    -- можно снова
    ready = true
-- конец функции
end)

Проверка

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