Roblox · Дополнительное

Ловушки: балка, шипы, пила

Три ловушки для полосы препятствий: вращающаяся балка сбивает и отбрасывает, шипы падают с потолка, когда наступаешь на плиту, пила ездит по рельсу туда-обратно.

Структура

Синим — что нужно создать.

Workspace
└─ Traps (Folder)
   ├─ SpinBeam (Model) — Center, Beam, Configuration (Speed, Damage), SpinnerServer
   ├─ FallingSpikes (Model) — Plate, Spikes, Configuration (Delay, Drop, Reset, Damage), SpikesServer
   └─ SawTrap (Model) — Rail, PointA, PointB, Saw, Configuration (Speed, Damage), SawServer

Шаги

  1. Все детали ловушек — Anchored. Двигает их скрипт (CFrame каждый кадр или TweenService).
  2. Урон: 10 раз в секунду скрипт проверяет, кто пересекается с ловушкой (workspace:GetPartsInPart). Это надёжнее Touched — у сдвигаемых деталей касания иногда теряются. Одного и того же бьёт не чаще раза в полсекунды.
  3. Балка: «Center» — ось, «Beam» — балка (CanCollide выкл.), Speed — градусов в секунду. Задетого отбрасывает в сторону.
  4. Шипы: плита «Plate» на полу и «Spikes» над ней. Наступил — плита краснеет, через Delay секунд шипы падают на Drop studs, через Reset поднимаются.
  5. Пила: «Saw» (цилиндр) ездит между «PointA» и «PointB» (невидимые точки), Speed — проходов в секунду.
  6. Урон идёт через TakeDamage — щит из «Усилений» от ловушек спасает.

Скрипты

SpinnerServer

Где: Workspace → Traps → SpinBeam · Script
Зачем: Вращение, урон и отброс.

-- события каждого кадра
local RunService = game:GetService("RunService")
-- крутящаяся балка
local model = script.Parent
-- ось
local center = model:WaitForChild("Center")
-- балка
local beam = model:WaitForChild("Beam")
-- Speed (градусов в секунду), Damage
local config = model:WaitForChild("Configuration")
-- где балка относительно оси
local offset = center.CFrame:ToObjectSpace(beam.CFrame)
-- угол поворота
local angle = 0
-- удаление по таймеру
local Debris = game:GetService("Debris")
-- когда кого били в последний раз
local hitTimes = setmetatable({}, {__mode = "k"})

-- урон всем, кто внутри детали
local function Hurt(part)
    -- детали, которые пересекаются с ловушкой
    for _, other in ipairs(workspace:GetPartsInPart(part)) do
        -- модель детали
        local victim = other:FindFirstAncestorOfClass("Model")
        -- живая?
        local humanoid = victim and victim:FindFirstChildOfClass("Humanoid")
        -- жива и давно не получала
        if humanoid and humanoid.Health > 0 and os.clock() - (hitTimes[humanoid] or 0) > 0.5 then
            -- запоминаем
            hitTimes[humanoid] = os.clock()
            -- урон
            humanoid:TakeDamage(config.Damage.Value)
            -- центр жертвы
            local root = victim:FindFirstChild("HumanoidRootPart")
            -- есть
            if root then
                -- от ловушки в сторону
                local away = (root.Position - part.Position) * Vector3.new(1, 0, 1)
                -- ровно в центре — любое направление
                if away.Magnitude < 0.1 then away = Vector3.new(1, 0, 0) end
                -- точка толчка
                local attachment = Instance.new("Attachment")
                -- в центр жертвы
                attachment.Parent = root
                -- отбрасывание
                local push = Instance.new("LinearVelocity")
                -- куда приложено
                push.Attachment0 = attachment
                -- без ограничения силы
                push.MaxForce = math.huge
                -- в сторону и вверх
                push.VectorVelocity = away.Unit * 40 + Vector3.new(0, 25, 0)
                -- толкаем
                push.Parent = root
                -- толчок короткий
                Debris:AddItem(push, 0.15)
                -- точку тоже убираем
                Debris:AddItem(attachment, 0.15)
            -- конец проверки
            end
        -- конец проверки
        end
    -- конец перебора
    end
-- конец функции
end

-- каждый кадр
RunService.Heartbeat:Connect(function(dt)
    -- поворачиваем
    angle += math.rad(config.Speed.Value) * dt
    -- балка вокруг оси
    beam.CFrame = center.CFrame * CFrame.Angles(0, angle, 0) * offset
-- конец обработчика
end)
-- постоянно
while true do
    -- 10 раз в секунду
    task.wait(0.1)
    -- кто задет — урон и отброс
    Hurt(beam)
-- конец цикла
end

SpikesServer

Где: Workspace → Traps → FallingSpikes · Script
Зачем: Шипы падают по плите.

-- плавное движение
local TS = game:GetService("TweenService")
-- ловушка с шипами
local model = script.Parent
-- плита на полу — наступил и сработало
local plate = model:WaitForChild("Plate")
-- шипы сверху
local spikes = model:WaitForChild("Spikes")
-- Delay, Drop, Reset, Damage
local config = model:WaitForChild("Configuration")
-- наверху
local up = spikes.CFrame
-- внизу
local down = up - Vector3.new(0, config.Drop.Value, 0)
-- ловушка сработала
local busy = false
-- удаление по таймеру
local Debris = game:GetService("Debris")
-- когда кого били в последний раз
local hitTimes = setmetatable({}, {__mode = "k"})

-- урон всем, кто внутри детали
local function Hurt(part)
    -- детали, которые пересекаются с ловушкой
    for _, other in ipairs(workspace:GetPartsInPart(part)) do
        -- модель детали
        local victim = other:FindFirstAncestorOfClass("Model")
        -- живая?
        local humanoid = victim and victim:FindFirstChildOfClass("Humanoid")
        -- жива и давно не получала
        if humanoid and humanoid.Health > 0 and os.clock() - (hitTimes[humanoid] or 0) > 1 then
            -- запоминаем
            hitTimes[humanoid] = os.clock()
            -- урон
            humanoid:TakeDamage(config.Damage.Value)
        -- конец проверки
        end
    -- конец перебора
    end
-- конец функции
end

-- на плиту наступили
plate.Touched:Connect(function(otherPart)
    -- уже работает или это не персонаж
    if busy or not otherPart.Parent:FindFirstChildOfClass("Humanoid") then return end
    -- сработала
    busy = true
    -- плита краснеет — предупреждение
    plate.Color = Color3.fromRGB(255, 80, 80)
    -- есть время отскочить
    task.wait(config.Delay.Value)
    -- шипы падают
    local fall = TS:Create(spikes, TweenInfo.new(0.15, Enum.EasingStyle.Quad, Enum.EasingDirection.In), {CFrame = down})
    -- вниз
    fall:Play()
    -- упали
    fall.Completed:Wait()
    -- кто под шипами — урон
    Hurt(spikes)
    -- лежат
    task.wait(config.Reset.Value)
    -- поднимаются
    TS:Create(spikes, TweenInfo.new(1), {CFrame = up}):Play()
    -- поднялись
    task.wait(1)
    -- плита серая
    plate.Color = Color3.fromRGB(120, 120, 120)
    -- готова снова
    busy = false
-- конец обработчика
end)

SawServer

Где: Workspace → Traps → SawTrap · Script
Зачем: Пила туда-обратно.

-- события каждого кадра
local RunService = game:GetService("RunService")
-- пила на рельсах
local model = script.Parent
-- диск
local saw = model:WaitForChild("Saw")
-- один конец рельса
local pointA = model:WaitForChild("PointA").Position
-- другой
local pointB = model:WaitForChild("PointB").Position
-- Speed (проходов в секунду), Damage
local config = model:WaitForChild("Configuration")
-- вращение диска
local spin = 0
-- удаление по таймеру
local Debris = game:GetService("Debris")
-- когда кого били в последний раз
local hitTimes = setmetatable({}, {__mode = "k"})

-- урон всем, кто внутри детали
local function Hurt(part)
    -- детали, которые пересекаются с ловушкой
    for _, other in ipairs(workspace:GetPartsInPart(part)) do
        -- модель детали
        local victim = other:FindFirstAncestorOfClass("Model")
        -- живая?
        local humanoid = victim and victim:FindFirstChildOfClass("Humanoid")
        -- жива и давно не получала
        if humanoid and humanoid.Health > 0 and os.clock() - (hitTimes[humanoid] or 0) > 0.5 then
            -- запоминаем
            hitTimes[humanoid] = os.clock()
            -- урон
            humanoid:TakeDamage(config.Damage.Value)
            -- центр жертвы
            local root = victim:FindFirstChild("HumanoidRootPart")
            -- есть
            if root then
                -- от ловушки в сторону
                local away = (root.Position - part.Position) * Vector3.new(1, 0, 1)
                -- ровно в центре — любое направление
                if away.Magnitude < 0.1 then away = Vector3.new(1, 0, 0) end
                -- точка толчка
                local attachment = Instance.new("Attachment")
                -- в центр жертвы
                attachment.Parent = root
                -- отбрасывание
                local push = Instance.new("LinearVelocity")
                -- куда приложено
                push.Attachment0 = attachment
                -- без ограничения силы
                push.MaxForce = math.huge
                -- в сторону и вверх
                push.VectorVelocity = away.Unit * 40 + Vector3.new(0, 25, 0)
                -- толкаем
                push.Parent = root
                -- толчок короткий
                Debris:AddItem(push, 0.15)
                -- точку тоже убираем
                Debris:AddItem(attachment, 0.15)
            -- конец проверки
            end
        -- конец проверки
        end
    -- конец перебора
    end
-- конец функции
end

-- каждый кадр
RunService.Heartbeat:Connect(function(dt)
    -- туда-обратно: от 0 до 1 и назад
    local alpha = (math.sin(time() * config.Speed.Value * math.pi) + 1) / 2
    -- диск крутится
    spin += dt * 15
    -- вдоль рельса
    local direction = (pointB - pointA).Unit
    -- место на рельсе; ось диска поперёк рельса — катится как колесо и вращается
    saw.CFrame = CFrame.lookAt(pointA:Lerp(pointB, alpha), pointA:Lerp(pointB, alpha) + direction) * CFrame.Angles(spin, 0, 0)
-- конец обработчика
end)
-- постоянно
while true do
    -- 10 раз в секунду
    task.wait(0.1)
    -- кто задет — урон и отброс
    Hurt(saw)
-- конец цикла
end

Проверка

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

Собрать ловушки одной командой