Функции в Luau для Roblox Studio

Этот курс подробно рассматривает работу с функциями в языке Luau, используемом в Roblox. Вы изучите синтаксис, передачу данных, типизацию и применение функций для обработки игровых событий.

1. Основы функций: синтаксис, объявление и вызов в скриптах

Основы функций: синтаксис, объявление и вызов в скриптах

Добро пожаловать в курс «Функции в Luau для Roblox Studio». Это первая и фундаментальная статья, с которой начнется ваше погружение в мир структурированного программирования. Если вы когда-либо писали скрипт, который становился слишком длинным, запутанным и сложным для чтения, то функции — это именно тот инструмент, который спасет вас от хаоса.

В этой статье мы разберем, что такое функции, зачем они нужны, как их правильно создавать (объявлять) и как заставлять их работать (вызывать). Мы будем использовать язык Luau — это версия Lua, адаптированная специально для Roblox.

Что такое функция и зачем она нужна?

Представьте, что вы пишете инструкцию для робота, как приготовить бутерброд. Если вам нужно сделать один бутерброд, вы просто пишете список действий: взять хлеб, намазать масло, положить сыр. Но что, если вам нужно сделать 100 бутербродов в разных местах вашей программы?

Копировать и вставлять один и тот же код 100 раз — плохая идея. Это делает скрипт огромным, а если вы решите заменить сыр на колбасу, вам придется искать и менять это в 100 местах. Здесь на помощь приходят функции.

Функция — это именованный блок кода, который можно написать один раз, а затем использовать (вызывать) столько раз, сколько потребуется. Это своего рода «мини-программа» внутри вашей основной программы.

!Концептуальная схема работы функции: вход, обработка, выход.

Принцип DRY

В программировании существует золотое правило: DRY (Don't Repeat Yourself — Не повторяйся). Функции — главный инструмент соблюдения этого принципа. Если вы видите, что пишете один и тот же код дважды, скорее всего, его нужно вынести в функцию.

Синтаксис объявления функции

В Luau существует несколько способов объявления функций, но мы начнем с самого распространенного и рекомендуемого — локальной функции. Использование ключевого слова local делает функцию доступной только в пределах текущего скрипта, что работает быстрее и безопаснее.

Базовая структура выглядит так:

Давайте разберем каждую часть этой конструкции:

  • local: Указывает, что функция является локальной переменной.
  • function: Ключевое слово, сообщающее Luau, что мы создаем функцию.
  • имяФункции: Уникальное имя, которое вы придумываете. Оно должно быть понятным и описывать действие (например, createPart, calculateScore, killPlayer). Принято использовать стиль camelCase (первая буква маленькая, каждое следующее слово с большой).
  • (): Круглые скобки. В них могут находиться параметры (о них мы поговорим чуть позже), но даже если их нет, скобки обязательны.
  • -- Тело функции: Код между объявлением и концом функции. Он не выполняется сразу, а только «запоминается» компьютером.
  • end: Ключевое слово, обозначающее конец блока функции.
  • Пример в Roblox Studio

    Откройте Roblox Studio, создайте Script в ServerScriptService и напишите следующий код:

    Если вы запустите игру (Play), то... ничего не произойдет. В окне Output будет пусто. Почему? Потому что мы только объявили функцию (научили скрипт, как это делать), но не вызвали её (не дали команду выполнить).

    Вызов функции

    Чтобы код внутри функции сработал, к ней нужно обратиться по имени. Это называется вызовом (call).

    Синтаксис вызова очень прост: вы пишете имя функции и обязательно ставите круглые скобки ().

    Теперь, при запуске скрипта, Luau увидит команду sayHello(), найдет функцию с таким именем и выполнит код внутри неё. В консоли появится: Привет, Роблокс!.

    Вы можете вызывать функцию сколько угодно раз:

    Это приведет к троекратному выводу сообщения.

    Важное правило: Порядок имеет значение

    В Luau (в отличие от некоторых других языков) вы обязаны объявить локальную функцию до того, как попытаетесь её вызвать. Скрипт читается сверху вниз.

    Ошибка:

    Правильно:

    Параметры и Аргументы

    Функции становятся по-настоящему мощными, когда мы можем передавать в них данные. Для этого используются параметры и аргументы.

    Параметры — это переменные, указанные в скобках при объявлении* функции. Они служат «заполнителями» для будущих данных. Аргументы — это конкретные значения, которые вы передаете в скобки при вызове* функции.

    Рассмотрим пример функции, которая приветствует конкретного игрока:

    Несколько параметров

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

    Допустим, нам нужно изменить прозрачность детали. Нам нужно знать, какую деталь менять и насколько.

    Если вы перепутаете порядок и напишете changeTransparency(0.5, myPart), скрипт выдаст ошибку, так как попытается присвоить число свойству Transparency объекта 0.5, что невозможно.

    Возврат значений (Return)

    Иногда нам нужно, чтобы функция не просто что-то сделала (например, написала в чат или поменяла цвет), а вернула результат вычислений обратно в основной код. Для этого используется ключевое слово return.

    Представьте математическую операцию сложения. Мы даем два числа, а в ответ хотим получить их сумму.

    Рассмотрим простую формулу:

    где — сумма, — первое слагаемое, — второе слагаемое.

    В коде это выглядит так:

    Когда Luau встречает слово return, функция немедленно прекращает свою работу и «превращается» в то значение, которое стоит после return. В примере выше вызов addNumbers(10, 5) фактически заменяется на число 15.

    Особенности return

  • Конец выполнения: Любой код, написанный после return внутри того же блока функции, никогда не выполнится.
  • Возврат нескольких значений: Luau позволяет возвращать сразу несколько значений через запятую.
  • Практический пример: Создание и настройка детали

    Давайте объединим полученные знания и напишем полезную функцию для Roblox Studio. Мы создадим функцию, которая спавнит куб случайного цвета в указанной позиции.

    В этом примере:

  • Мы объявили функцию spawnCube.
  • Она принимает один параметр position.
  • Внутри она создает деталь, настраивает её свойства.
  • Она возвращает созданную деталь (return part), чтобы мы могли изменить её свойства позже (например, прозрачность cube1).
  • Область видимости (Scope) и локальные функции

    Почему мы везде пишем local? В Luau переменные и функции могут быть глобальными или локальными.

    * Global: Если не написать local, функция станет глобальной. Это считается плохой практикой, так как глобальные переменные медленнее и могут конфликтовать с другими скриптами или частями кода. * Local: Локальная функция видна только в том блоке кода, где она создана. Это стандарт индустрии.

    > Всегда используйте local function, если у вас нет веской причины делать иначе. Это сделает ваш код чище и быстрее.

    Частые ошибки новичков

  • Забытые скобки: Написание sayHello без () не вызовет функцию, а просто сошлется на неё как на переменную.
  • Вызов до объявления: Попытка вызвать локальную функцию в строке 1, если она написана в строке 10.
  • Отсутствие end: Каждая функция должна закрываться ключевым словом end. Roblox Studio обычно подсказывает это, но будьте внимательны.
  • Путаница с аргументами: Передача аргументов в неверном порядке (например, передача цвета вместо позиции).
  • Заключение

    Сегодня вы сделали огромный шаг в изучении Luau. Функции — это скелет любого сложного проекта в Roblox. Они позволяют разбивать большие задачи на маленькие, управляемые части.

    Краткий итог: * Функции позволяют переиспользовать код. * Объявляются через local function Name() ... end. * Вызываются через Name(). * Могут принимать данные (параметры) и возвращать результаты (return).

    В следующей статье мы углубимся в работу с событиями и узнаем, как вызывать функции не просто так, а когда игрок касается детали или нажимает кнопку.

    2. Работа с данными: параметры, аргументы и возвращаемые значения

    Работа с данными: параметры, аргументы и возвращаемые значения

    Приветствую вас, студенты! В прошлой лекции мы заложили фундамент: научились объявлять и вызывать функции. Однако наши функции были «статичными» — они всегда выполняли одно и то же действие, например, просто печатали «Привет». В реальной разработке на Roblox Studio этого недостаточно.

    Представьте, что вам нужно создать функцию, которая наносит урон игроку. Если вы напишете функцию, которая всегда отнимает ровно 10 единиц здоровья, вам придется писать отдельные функции для урона в 20, 50 или 100 единиц. Это неудобно и нарушает принцип DRY (Don't Repeat Yourself).

    Сегодня мы сделаем наши функции гибкими и умными. Мы научим их принимать информацию извне (параметры и аргументы) и отдавать результат своей работы обратно (возвращаемые значения).

    Параметры и аргументы: В чем разница?

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

    !Визуализация процесса передачи данных в функцию: параметр — это место для приема, аргумент — это конкретные данные.

    Параметры (Parameters)

    Параметры — это переменные, которые вы указываете в круглых скобках при объявлении функции. Это «заготовки» или «слоты», которые ждут, когда в них положат данные. Они существуют только внутри функции.

    В примере выше message и count — это параметры. Мы еще не знаем, что именно мы будем печатать и сколько раз, но мы подготовили логику для обработки этих данных.

    Аргументы (Arguments)

    Аргументы — это конкретные значения, которые вы передаете в функцию при её вызове. Это данные, которые заполняют слоты параметров.

    > «Параметр — это переменная в объявлении функции. Аргумент — это фактическое значение этой переменной, переданное при вызове».

    Работа с множеством параметров

    Luau позволяет передавать в функцию столько параметров, сколько вам нужно. Они перечисляются через запятую.

    Порядок имеет значение

    Самое важное правило: порядок передачи аргументов должен строго соответствовать порядку параметров.

    Рассмотрим функцию создания детали:

    Если мы вызовем её так:

    Всё сработает отлично. Первый аргумент попадет в color, второй — в size, третий — в position.

    Но если мы перепутаем порядок:

    Скрипт выдаст ошибку. Он попытается присвоить вектор свойству BrickColor (параметр color), что невозможно.

    Необязательные аргументы и nil

    В Luau, если вы объявили функцию с 3 параметрами, а при вызове передали только 2, третий параметр автоматически получит значение nil (пустота).

    Это можно использовать для создания значений по умолчанию:

    Возвращаемые значения (Return)

    До сих пор наши функции что-то делали (печатали текст, создавали детали), но не отдавали результат обратно в код. Чтобы получить результат вычислений из функции, используется ключевое слово return.

    Зачем нужен return?

    Представьте, что вы просите повара приготовить пиццу. Вы даете ему ингредиенты (аргументы). Он готовит (тело функции). Но если он не отдаст вам пиццу (return), а просто съест её на кухне (print), вы останетесь голодными.

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

    Математический пример

    Давайте напишем функцию для расчета урона с учетом множителя критического удара. Нам понадобится формула:

    Где: * — итоговый урон. * — базовый урон оружия. * — множитель (например, 2 для критического удара, 1 для обычного).

    Реализация в коде:

    Если бы мы использовали print внутри функции вместо return, переменная myDamage получила бы значение nil, и математическая операция 100 - nil вызвала бы ошибку.

    Прерывание функции

    Ключевое слово return работает как знак «Стоп». Как только Luau видит return, выполнение функции немедленно прекращается, и значение возвращается. Любой код, написанный после return в том же блоке, никогда не выполнится.

    Возврат нескольких значений

    Одной из мощных особенностей Luau является возможность возвращать сразу несколько значений из одной функции. Это очень полезно в GameDev, когда, например, нужно вернуть позицию и статус операции одновременно.

    Синтаксис прост: перечислите возвращаемые значения через запятую.

    Если вы примете меньше переменных, чем возвращает функция, лишние значения просто отбросятся. Если больше — лишние переменные станут nil.

    Практика: Функция поиска дистанции

    Давайте создадим полезную для Roblox функцию, которая вычисляет расстояние между двумя точками, но возвращает не только само расстояние, но и логическое значение: находится ли цель в радиусе атаки.

    Для расчета расстояния в трехмерном пространстве используется формула длины вектора, но в Luau у векторов есть встроенное свойство .Magnitude. Однако для понимания процесса, математически расстояние вычисляется так:

    Где: * — расстояние между точками. * — координаты первой точки. * — координаты второй точки.

    В Luau мы упростим это, используя встроенные средства:

    Частые ошибки

  • Путаница с типами данных: Если функция ожидает число, а вы передали строку, Luau может выдать ошибку при попытке математических операций. Всегда следите за тем, что вы передаете.
  • Забытый return: Если вы забыли написать return, функция вернет nil. Это частая причина ошибок "Attempt to perform arithmetic on nil".
  • Игнорирование возвращаемого значения: Вызов функции calculateDamage(10, 2) без присваивания результата переменной (например, local d = ...) приведет к тому, что вычисленное значение просто исчезнет в никуда.
  • Заключение

    Теперь ваши функции — это полноценные инструменты. Они могут принимать сырые данные, обрабатывать их по сложным формулам и возвращать готовый результат. Это основа любой сложной механики в Roblox, от системы инвентаря до искусственного интеллекта врагов.

    В следующей статье мы разберем анонимные функции и узнаем, как передавать функции в качестве аргументов другим функциям (callback), что критически важно для обработки событий (нажатий клавиш, касаний).

    Удачи в коде!

    3. Области видимости, анонимные функции и замыкания

    Области видимости, анонимные функции и замыкания

    Приветствую вас, разработчики! Мы уже научились создавать классические функции, передавать в них данные и получать ответы. Казалось бы, что еще нужно? Но Luau скрывает в себе механизмы, которые превращают простого скриптера в архитектора сложных систем.

    Сегодня мы заглянем «под капот» языка. Мы разберем, почему одни переменные видны везде, а другие исчезают; научимся создавать функции-призраки без имени и узнаем магию замыканий, которая позволяет функциям «помнить» прошлое.

    Область видимости (Scope)

    Область видимости — это набор правил, определяющих, где в вашем коде доступна та или иная переменная. Понимание этого механизма критически важно для предотвращения ошибок, когда скрипт «не видит» данные или, наоборот, случайно перезаписывает важную информацию.

    В Luau область видимости можно представить как тонированные стекла в автомобиле: изнутри вы видите всё, что происходит снаружи, но снаружи никто не видит, что происходит внутри.

    !Визуализация иерархии областей видимости: доступ к данным идет изнутри наружу.

    Глобальные и локальные переменные

  • Глобальные переменные: Объявляются без ключевого слова local. Они доступны в любом месте скрипта (и иногда даже за его пределами, в зависимости от окружения, но в Roblox Studio глобальные переменные ограничены текущим скриптом).
  • Локальные переменные: Объявляются с ключевым словом local. Они существуют только в том блоке кода, где были созданы.
  • Рассмотрим пример:

    Блочная область видимости

    В Luau любой блок кода, ограниченный словами do ... end, then ... end, repeat ... until, создает свою маленькую область видимости.

    > Золотое правило: Всегда используйте local, если у вас нет веской причины делать иначе. Локальные переменные работают быстрее, так как процессор обращается к ним через регистры или стек, а не через глобальную таблицу.

    Анонимные функции

    До сих пор мы давали всем функциям имена: local function jump(). Но что, если функция нужна нам всего один раз, и придумывать ей имя нет смысла? Здесь на сцену выходят анонимные функции.

    Анонимная функция — это функция без имени. Она создается «на лету» и часто используется как значение.

    Синтаксис

    Обычная функция:

    Анонимная функция:

    Сама по себе такая запись вызовет ошибку синтаксиса, если её никуда не применить. Анонимную функцию можно сохранить в переменную:

    Использование в Roblox Studio (Callbacks)

    Самое частое применение анонимных функций в Roblox — это обработка событий (Events). Например, когда игрок касается детали.

    Вместо того чтобы создавать отдельную именованную функцию и потом привязывать её, мы пишем функцию прямо внутри скобок Connect:

    Это делает код компактнее и читабельнее, так как логика обработки находится ровно там, где происходит подписка на событие.

    Замыкания (Closures)

    Теперь мы подходим к самой интересной и мощной концепции. Замыкание — это способность функции «запоминать» переменные из той области видимости, где она была создана, даже если эта область видимости уже завершила свою работу.

    Звучит сложно? Давайте разберем на примере счетчика.

    Представьте, что нам нужно считать, сколько раз игрок нажал на кнопку. Если мы используем глобальную переменную, любой другой скрипт может её случайно изменить. Если мы используем локальную переменную внутри функции, она будет сбрасываться каждый раз.

    Решение — замыкание.

    Как это работает?

  • Мы вызываем createCounter. Внутри создается локальная переменная count.
  • Функция возвращает новую анонимную функцию.
  • Обычно, после завершения createCounter, переменная count должна была бы исчезнуть.
  • Но так как возвращаемая анонимная функция использует count, Luau сохраняет count в специальное хранилище, привязанное к этой конкретной функции. Это называется Upvalue (внешняя локальная переменная).
  • Фабрика функций

    Замыкания позволяют создавать «фабрики» функций. Например, создадим генератор функций, которые умножают число на заданный коэффициент.

    Здесь double и triple — это две разные функции, созданные по одному шаблону, но у каждой из них свое «воспоминание» о переменной factor.

    Практический пример: Система наград

    Давайте объединим знания. Мы создадим систему, которая выдает награду игроку, но с ограничением: награду можно получить только один раз. Мы используем замыкание, чтобы хранить состояние «получена ли награда», не загрязняя глобальную область видимости.

    В этом примере переменная isClaimed надежно спрятана внутри замыкания. Никакой другой скрипт не может случайно изменить её на false и взломать систему наград.

    Заключение

    Сегодня вы перешли на новый уровень понимания Luau.

    * Области видимости помогают держать код в чистоте и безопасности. * Анонимные функции позволяют писать код быстрее и элегантнее, особенно при работе с событиями Roblox. * Замыкания открывают дверь к мощным техникам программирования, позволяя сохранять данные внутри функций.

    В следующей статье мы разберем таблицы (Tables) — универсальную структуру данных в Luau, которая заменит вам массивы, словари и даже объекты.

    4. Особенности Luau: строгая типизация функций и вариативные аргументы

    Особенности Luau: строгая типизация функций и вариативные аргументы

    Приветствую вас, студенты! Мы уже прошли большой путь: от простых команд print до создания замыканий и фабрик функций. Вы уже умеете писать код, который работает. Но в профессиональной разработке на Roblox важно не только то, чтобы код работал, но и то, чтобы он был надежным и предсказуемым.

    Вы наверняка сталкивались с ситуацией, когда скрипт ломается, потому что вы случайно передали в функцию деталь (Part) вместо числа, или забыли один из аргументов. В стандартном Lua это приводит к ошибкам во время игры. Но Luau — язык, на котором работает Roblox, — предлагает мощные инструменты для предотвращения таких проблем еще до запуска игры.

    Сегодня мы изучим две продвинутые темы: строгую типизацию (Type Checking), которая превратит Roblox Studio в вашего личного контролера качества, и вариативные аргументы (...), которые дадут вашим функциям безграничную гибкость.

    Строгая типизация (Type Checking)

    Изначально Lua — это язык с динамической типизацией. Это значит, что переменная может хранить сначала число, потом строку, а потом ссылку на объект. Это удобно для быстрых набросков, но ужасно для больших проектов.

    Luau добавляет возможность постепенной типизации. Вы можете явно указать скрипту, какой тип данных должна принимать функция и какой тип она должна возвращать.

    Включение строгого режима

    Чтобы магия типов заработала в полную силу, первую строчку вашего скрипта нужно начать со специального комментария:

    Этот флаг сообщает анализатору кода Roblox Studio, что вы хотите получать предупреждения о любых несоответствиях типов.

    Типизация параметров

    Синтаксис типизации прост: после имени параметра ставится двоеточие : и указывается тип.

    Основные типы, которые вы будете использовать: * number — любые числа. * string — текст. * boolean — истина или ложь (true/false). * nil — пустота. * any — любой тип (отключает проверку для конкретной переменной). * Instance — любой объект Roblox. * Part, Model, Vector3 — конкретные классы Roblox.

    Типизация возвращаемых значений

    Вы также можете указать, что именно функция обязана вернуть. Это делается после закрывающей скобки параметров, также через двоеточие.

    Если вы напишете такую функцию, но внутри случайно вернете строку или забудете return, редактор кода сразу укажет на ошибку.

    !Визуализация работы проверки типов: функция пропускает внутрь только данные разрешенного формата.

    Опциональные типы

    Иногда аргумент может быть числом, а может и отсутствовать (быть nil). Для этого используется знак вопроса ? после типа.

    Вариативные аргументы (Varargs)

    Иногда мы заранее не знаем, сколько аргументов передадут в нашу функцию. Вспомните функцию print(). Вы можете написать print("A"), а можете print("A", "B", "C", 1, 2, 3). Она принимает любое количество данных.

    В Luau для этого используется оператор многоточия (...).

    Синтаксис и использование

    Многоточие ставится в конце списка параметров. Внутри функции ... представляет собой список всех переданных «лишних» аргументов.

    Однако просто передать ... дальше — это скучно. Чаще всего мы хотим обработать эти данные. Для этого вариативные аргументы обычно упаковывают в таблицу (о таблицах мы подробно поговорим в следующей статье, пока считайте это просто контейнером или списком).

    Практический пример: Сумматор

    Давайте напишем функцию, которая складывает любое количество чисел.

    Математически мы хотим реализовать операцию суммы ряда:

    Где: * — итоговая сумма. * — количество переданных аргументов. * — значение -го аргумента (первого, второго и т.д.). * — знак суммирования.

    Реализация в Luau:

    Комбинирование обычных и вариативных аргументов

    Вы можете смешивать фиксированные параметры и .... Важно помнить: многоточие всегда должно быть последним.

    В этом примере:

  • "Alex" попадет в переменную firstPlace.
  • "Bob", "Charlie" и "Dave" попадут в ....
  • Зачем использовать типизацию и Varargs?

  • Безопасность: Типизация спасает от глупых ошибок. Если функция ожидает Vector3, а вы даете ей number, скрипт даже не запустится, спасая вас от долгих поисков бага.
  • Автодополнение (IntelliSense): Когда вы указываете тип part: Part, Roblox Studio знает все свойства детали. Как только вы поставите точку после part, вам предложат Transparency, Color, Position и другие свойства. Без типизации редактор не знает, что это за переменная, и не может помочь.
  • Гибкость: Вариативные аргументы позволяют создавать универсальные инструменты, которые адаптируются под ситуацию, подобно швейцарскому ножу.
  • Заключение

    Сегодня вы сделали свой код профессиональным. Использование --!strict и указание типов — это стандарт индустрии в Roblox-разработке. Это дисциплинирует ум и делает архитектуру игры чистой.

    Мы также затронули тему упаковки аргументов в список {...}. Это подводит нас к самой важной структуре данных в Luau. В следующей статье мы наконец-то разберем Таблицы (Tables) — универсальный инструмент, который заменяет массивы, словари и объекты, и узнаем, как хранить инвентарь игрока или базу данных сервера.

    5. Практика в Roblox: использование функций для обработки событий и сигналов

    Практика в Roblox: использование функций для обработки событий и сигналов

    Добро пожаловать на одну из самых захватывающих лекций нашего курса! До этого момента мы изучали функции в своего рода «вакууме». Мы писали код, запускали его, и он выполнялся линейно: сверху вниз. Но игры так не работают.

    Игры — это интерактивные системы. Они ждут действий игрока: нажатия клавиши, клика мышкой, касания детали персонажем. В Roblox Studio механизм, который связывает действие (событие) и реакцию (функцию), называется системой сигналов.

    Сегодня мы научимся «оживлять» наши функции, заставляя их срабатывать автоматически в нужный момент. Мы разберем методы Connect и Disconnect, узнаем, какие аргументы движок Roblox передает нам скрытно, и создадим свои первые игровые механики.

    Что такое событие (Event)?

    В мире Roblox практически каждый объект (Instance) имеет набор Событий (Events). Это специальные сигналы, которые срабатывают, когда происходит что-то конкретное.

    * У детали (Part) есть событие Touched (коснулись). * У игрока (Player) есть событие Chatted (написал в чат). * У кнопки (ClickDetector) есть событие MouseClick (кликнули мышкой).

    Представьте, что функция — это электрическая лампочка. Она умеет светить, но для этого ей нужно электричество. Событие — это выключатель. Пока вы не соедините выключатель с лампочкой проводами, свет не загорится.

    !Схематичное изображение того, как метод Connect связывает событие и функцию.

    Метод :Connect()

    Чтобы «подключить» вашу функцию к событию, используется метод :Connect(). Это мост между тем, что случилось, и тем, что нужно сделать.

    Синтаксис выглядит так:

    Важное правило передачи функции

    Обратите внимание: когда мы передаем функцию в Connect, мы пишем её имя без скобок ().

    * myFunction() — это вызов функции (сделай это прямо сейчас и верни результат). * myFunction — это ссылка на функцию (вот тебе инструкция, используй её потом).

    Если вы напишете Connect(myFunction()), скрипт выполнит функцию один раз при запуске игры, а в Connect передаст то, что функция вернула (обычно nil), и событие работать не будет.

    Практика: Создание «Убивающего блока» (Kill Brick)

    Давайте создадим классическую механику Roblox — красную деталь, которая наносит урон при касании. Это идеальный пример работы с событием Touched.

    Шаг 1: Подготовка функции

    Когда срабатывает событие Touched, Roblox автоматически запускает привязанную функцию и передает ей один аргумент: ту деталь, которая коснулась нашей детали. Назовем этот параметр hit.

    Шаг 2: Подключение

    Теперь свяжем событие и функцию:

    Теперь, как только любой объект (игрок или физический куб) коснется trapPart, Luau вызовет onTrapTouched и передаст коснувшуюся деталь в параметр hit.

    Скрытые аргументы событий

    Откуда мы узнали, что Touched передает именно hit? Это задокументировано в API Roblox. Каждое событие передает свой набор аргументов.

    Рассмотрим событие PlayerAdded сервиса Players. Оно срабатывает, когда игрок заходит на сервер.

    Если бы мы использовали анонимную функцию (о которой говорили в прошлой статье), код стал бы компактнее:

    > Совет: Всегда проверяйте документацию Roblox (Roblox Creator Documentation), чтобы узнать, какие именно аргументы передает конкретное событие.

    Управление соединением: RBXScriptConnection

    Когда вы используете :Connect(), этот метод возвращает специальный объект — RBXScriptConnection. Это «чек» о том, что подписка оформлена.

    Иногда нам нужно, чтобы событие сработало только один раз или перестало работать при определенном условии. Для этого используется метод :Disconnect().

    Пример: Одноразовая кнопка

    Представьте кнопку, которая дает золото, но нажать её можно только один раз за всю игру.

    Если не отключить соединение, игроки смогут кликать бесконечно. Кроме того, отключение ненужных событий помогает оптимизировать игру, освобождая память.

    Математика в игровой логике

    Часто внутри функций-обработчиков нам нужно производить вычисления. Например, мы хотим не убивать игрока мгновенно, а отнимать здоровье пропорционально защите.

    Формула расчета конечного здоровья может выглядеть так:

    Где: * — новое значение здоровья игрока после удара. * — текущее здоровье игрока в момент удара. * — базовый урон ловушки (Damage). * — коэффициент защиты брони (Resistance), от 0 до 1 (где 0.1 = 10% защиты).

    Реализуем это в коде с использованием строгой типизации, которую мы изучили ранее:

    В этой формуле выражение вычисляет, какую долю урона персонаж получит. Если защита (20%), то персонаж получит (80%) от базового урона.

    Частые ошибки при работе с событиями

    1. Подключение внутри цикла

    Это самая страшная ошибка новичка, которая может «повесить» сервер.

    НЕПРАВИЛЬНО:

    ПРАВИЛЬНО: Подключайте события один раз при запуске скрипта (вне циклов).

    2. Забытая проверка на Humanoid

    Событие Touched срабатывает от всего: от пола, от стен, от падающих предметов. Если вы попытаетесь найти Humanoid у стены, вы получите nil. Попытка обратиться к nil.Health вызовет ошибку. Всегда проверяйте: if humanoid then ... end.

    Заключение

    События и сигналы — это нервная система вашей игры. Функции больше не лежат мертвым грузом, они реагируют на мир.

    Мы научились:

  • Использовать :Connect() для связи события и функции.
  • Принимать автоматические аргументы (как hit или player).
  • Использовать :Disconnect() для создания одноразовых механик.
  • Применять математику для расчета игровых параметров.
  • В следующей статье мы углубимся в Таблицы (Tables) — самую мощную структуру данных в Luau, которая позволит нам создавать инвентари, списки лидеров и сложные базы данных.