KillBrick в Roblox делают через серверный Script внутри опасного Part и событие Touched. Скрипт находит модель персонажа, получает Humanoid и вызывает TakeDamage(). Cooldown нужен, потому что событие могут одновременно вызвать несколько частей аватара.
Опасный блок кажется простой первой механикой, но на нём удобно понять события Roblox. Движок сообщает, какая деталь коснулась Part. Скрипт не получает игрока напрямую: сначала нужно подняться к модели персонажа и найти Humanoid. Если просто присвоить Health ноль при каждом касании, код сработает, но вы не увидите, почему иногда обработчик вызывается несколько раз и как позже сделать лаву с постепенным уроном.
Опасная деталь с включённым CanTouch и серверным Script.
Событие передаёт конкретную часть, которая вошла в контакт.
Не даёт руке, ноге и туловищу нанести несколько ударов подряд.

KillBrick Roblox скрипт с контролем повторного урона
Создайте Part, назовите его KillBrick, включите Anchored и оставьте CanTouch активным. Добавьте внутрь обычный Script, не LocalScript. Таблица cooldowns хранит Humanoid, которым недавно нанесли урон. Через секунду запись удаляется. Такой вариант подходит для фиксированного урона и легко превращается в кислоту, шипы или горячий пол.
local killBrick = script.Parent
local damage = 35
local cooldowns = {}
local function onTouched(hit)
local character = hit:FindFirstAncestorOfClass("Model")
if not character then
return
end
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid or cooldowns[humanoid] then
return
end
-- Не разрешаем частям одного аватара нанести двойной урон
cooldowns[humanoid] = true
humanoid:TakeDamage(damage)
task.delay(1, function()
cooldowns[humanoid] = nil
end)
end
killBrick.Touched:Connect(onTouched)- Первое касание: здоровье уменьшается на 35
- Повторные касания в течение секунды: игнорируются
Использование Humanoid как ключа связывает cooldown с конкретным персонажем. Другой игрок в ту же секунду всё равно получит урон. После удаления персонажа ссылка исчезнет из таблицы при завершении задержки. Для мгновенной смерти замените вызов на humanoid.Health = 0, но для обучения полезнее видеть число урона и проверять несколько касаний.
Настройки опасного блока
| Элемент | Что означает | Что делать |
|---|---|---|
| damage | 35 | Сколько здоровья снимает одно разрешённое касание |
| cooldown | 1 секунда | Интервал между ударами по одному Humanoid |
| Anchored | true | Блок не падает под действием физики |
| CanTouch | true | Событие Touched может срабатывать |
| Script | внутри Part | Код выполняется на сервере |
При тесте откройте Output и временно добавьте print(hit.Name). Вы увидите, что блок касается разных частей аватара. Затем удалите лишний лог. Проверьте R6 и R15, прыжок на край блока и ситуацию, когда два игрока касаются лавы одновременно. Механика должна одинаково менять здоровье у всех клиентов, потому что решение принимает сервер.

Практика: соберите KillBrick и поймайте двойное срабатывание Touched
Откройте пустой Baseplate и соберите блок с нуля: Part с именем KillBrick, внутри обычный Script, damage равен 35, cooldown равен одной секунде. Успех выглядит так: за одно касание здоровье падает со 100 до 65 ровно один раз, хотя в Output видно несколько имён частей аватара. Всё делайте в Workspace, LocalScript здесь не нужен.
- Part с именем KillBrick. Вставьте Part в Workspace, переименуйте в KillBrick и в Properties включите Anchored, а CanTouch оставьте включённым. После этого блок висит на месте и не уезжает, когда персонаж в него упирается.
- Обычный Script внутри блока. Добавьте внутрь Part именно Script, а не LocalScript, и вставьте код с таблицей cooldowns и функцией onTouched. Нажмите Play: в Output не должно быть красных строк, пока вы не подошли к блоку.
- Первое касание и Health. Наведите персонажа на блок и посмотрите свойство Health у Humanoid в проводнике во время игры. Значение должно один раз уменьшиться со 100 до 65, а не обнулиться.
- Временный print(hit.Name). Добавьте первой строкой onTouched вызов print(hit.Name) и коснитесь блока снова. В Output появятся несколько имён подряд: LeftFoot, RightFoot, LowerTorso, а TakeDamage при этом сработает один раз.
- Пауза в одну секунду. Встаньте на блок и не сходите с него: task.delay через секунду чистит cooldowns[humanoid], поэтому здоровье уходит по цепочке 100, 65, 30 и дальше до нуля с шагом примерно в секунду. Убедитесь в ритме и удалите строку с print.
Теперь сломайте связку намеренно. Замените поиск модели строкой local character = hit и запустите заново: FindFirstChildOfClass("Humanoid") вернёт nil у LeftFoot, функция выйдет по return и урон вообще перестанет проходить. Второй эксперимент: уберите таблицу cooldowns и поставьте один общий флаг debounce, после чего зайдите вдвоём через Play Here и Local Server: второй игрок пройдёт по блоку без урона, пока не истечёт секунда у первого. Верните оба куска кода и проверьте, что урон снова 35 на каждого персонажа.
Дальше вынесите damage и cooldown в Attributes самого Part, чтобы одна копия скрипта обслуживала и шипы, и кислоту, и горячий пол без правки кода. Сделайте вариант лавы: вместо разового TakeDamage крутите цикл с task.wait(0.5), пока персонаж стоит на блоке, и останавливайте его по событию TouchEnded. Затем повесьте на Humanoid.Died счётчик смертей и выведите его в leaderstats.
Частые ошибки и почему они появляются
Если скрипт не работает, сначала проверьте его тип и место. LocalScript внутри обычного Part в Workspace обычно не запускается так, как ожидает новичок. Если урон проходит десять раз подряд, причина не в TakeDamage, а в количестве событий Touched. Если блок двигается вместе с игроком, скорее всего, он не закреплён или является частью другой сборки.
Событие часто передаёт руку или ногу. Humanoid лежит в модели персонажа, поэтому нужен подъём к предку.
Глобальный debounce заблокирует урон всем игрокам. Используйте таблицу с отдельным ключом на Humanoid.
Пламя и красный материал не наносят урон сами. Результат проверяйте по Health.
Самопроверка
Почему Touched срабатывает несколько раз за одно касание?
Touched срабатывает отдельно для каждой детали аватара, которая вошла в контакт: ступня, вторая ступня и туловище задевают блок почти одновременно. Поэтому обработчик вызывается подряд несколько раз, и повторный урон гасят таблицей cooldowns с задержкой в секунду.
Почему для KillBrick нужен обычный Script, а не LocalScript?
Обычный Script внутри Part выполняется на сервере, поэтому снятое здоровье одинаково видят все игроки. LocalScript в Workspace обычно просто не запускается, и урон либо не проходит, либо остаётся только на одном клиенте.
Чем таблица cooldowns лучше одного флага debounce?
Таблица cooldowns хранит отдельную запись на каждый Humanoid, поэтому пауза действует только для того персонажа, которому уже нанесли урон. Один общий флаг заблокировал бы блок целиком: второй игрок пробежал бы по лаве без потери здоровья.
Почему нельзя искать Humanoid прямо в hit?
В hit приходит конкретная деталь вроде LeftFoot или LowerTorso, а Humanoid лежит уровнем выше, в модели персонажа. Поэтому скрипт сначала поднимается к предку через FindFirstAncestorOfClass("Model") и только потом берёт FindFirstChildOfClass("Humanoid").
Как сделать мгновенную смерть вместо урона в 35 единиц?
Мгновенная смерть получается заменой humanoid:TakeDamage(damage) на humanoid.Health = 0. Для обучения удобнее оставить число урона: так видно, что срабатывание было одно, а не десять подряд.
Зачем KillBrick ставить Anchored?
Anchored со значением true выключает физику для блока, и он остаётся на месте при столкновении с персонажем. Без этого блок может поехать вместе с игроком или упасть с платформы, и ловушка перестанет работать там, где вы её поставили.
Что делать дальше
Сначала добейтесь стабильного урона на одном блоке. Потом вынесите damage и cooldown в Attributes, чтобы настраивать разные ловушки без копирования кода. Основы функций, таблиц и событий можно закрепить на курсе Lua. Дальше подключите leaderstats для счёта смертей и прочитайте разбор ошибок Studio, если Output показывает nil или неверный путь.
