Урок 7 из 15

События: код, который ждёт, а не опрашивает

Подписываться на события движка и не плодить лишние подписки.

Теория

Событие — сигнал «что-то случилось»: игрок зашёл, деталь коснулась другой, кнопка нажата. Вместо того чтобы проверять это в цикле, код подписывается функцией через Connect и ждёт, пока его позовут.

Connect возвращает соединение. Пока оно живо, функция будет вызываться. Disconnect обрывает подписку — это важно, потому что забытые подписки накапливаются и держат объекты в памяти.

Wait останавливает выполнение до ближайшего срабатывания и возвращает его аргументы. Своё событие внутри одной стороны делают через BindableEvent, между сервером и клиентом — через RemoteEvent.

  • Обработчик получает те же аргументы, которые передаёт событие
  • Touched срабатывает много раз подряд — нужна защита от повторов
  • Одно событие может иметь сколько угодно подписчиков
  • Подписки внутри цикла — верный способ подписаться сто раз

Пример

Деталь награждает игрока при касании, но не чаще раза в секунду.

ServerScriptService/Events.lua
  1. local pad = workspace:WaitForChild("CoinPad")
  2. local busy = false
  3.  
  4. local connection = pad.Touched:Connect(function(hit)
  5. if busy then
  6. return
  7. end
  8.  
  9. local humanoid = hit.Parent and hit.Parent:FindFirstChild("Humanoid")
  10.  
  11. if not humanoid then
  12. return
  13. end
  14.  
  15. busy = true
  16. print("Награда выдана")
  17. task.wait(1)
  18. busy = false
  19. end)

Переменная connection пригодится, когда подписку нужно будет оборвать.

Задача

Подпишись на вход игрока в игру и выведи его имя. Через десять секунд после входа обработчик должен отключиться и больше не срабатывать.

  • Players.PlayerAdded — событие входа
  • Соединение хранится в переменной, у него есть метод Disconnect
Показать решение
ServerScriptService/Solution.lua
  1. local Players = game:GetService("Players")
  2.  
  3. local connection
  4.  
  5. connection = Players.PlayerAdded:Connect(function(player)
  6. print(player.Name .. " зашёл")
  7. end)
  8.  
  9. task.delay(10, function()
  10. connection:Disconnect()
  11. print("Подписка отключена")
  12. end)

Проверь себя

Что возвращает вызов Connect?

Показать ответ

Connect возвращает объект соединения с методом Disconnect.

Почему у Touched нужна защита от повторов?

Показать ответ

Персонаж касается детали несколькими частями тела и не один кадр подряд.