Объекты: метатаблицы и привычный класс
Писать классы в принятом для Roblox стиле и понимать, что делает __index.
Теория
Классов в Luau нет — есть таблицы и метатаблицы. Метатаблица описывает поведение таблицы, а поле __index говорит: «если ключа здесь нет, ищи его вот там». Так объект получает доступ к методам класса.
Метод объявляют через двоеточие: function Enemy:takeDamage(amount). Двоеточие незаметно добавляет первый аргумент self — сам объект. Вызывают тоже через двоеточие.
Конструктор по традиции называют new: он создаёт таблицу с полями и привязывает к ней метатаблицу класса.
- Enemy.__index = Enemy — типовая строка, без неё методы не найдутся
- Точка вместо двоеточия при вызове метода — и self окажется первым аргументом
- Классы обычно живут в ModuleScript
- Не наследуй всё подряд: в игровом коде композиция чаще проще
Пример
Класс врага с здоровьем и уроном.
local Enemy = {}Enemy.__index = Enemyfunction Enemy.new(name: string, health: number)local self = setmetatable({}, Enemy)self.name = nameself.health = healthreturn selfendfunction Enemy:takeDamage(amount: number)self.health = math.max(0, self.health - amount)if self.health == 0 thenprint(self.name .. " повержен")endendreturn Enemy
Задача
Сделай класс Chest: у сундука есть содержимое и признак «открыт». Метод open возвращает содержимое и помечает сундук открытым, повторное открытие возвращает nil.
- Признак храни прямо в self
- Проверку «уже открыт» делай в начале метода
Показать решение
local Chest = {}Chest.__index = Chestfunction Chest.new(loot: string)local self = setmetatable({}, Chest)self.loot = lootself.opened = falsereturn selfendfunction Chest:open(): string?if self.opened thenreturn nilendself.opened = truereturn self.lootendreturn Chest
Проверь себя
Что делает поле __index в метатаблице?
Показать ответ
__index — правило поиска: не нашли в объекте, идём в класс.
Чем отличается вызов obj:method() от obj.method()?
Показать ответ
Двоеточие — сокращение для передачи self, точка этого не делает.