Урок 9 из 15

Объекты: метатаблицы и привычный класс

Писать классы в принятом для Roblox стиле и понимать, что делает __index.

Теория

Классов в Luau нет — есть таблицы и метатаблицы. Метатаблица описывает поведение таблицы, а поле __index говорит: «если ключа здесь нет, ищи его вот там». Так объект получает доступ к методам класса.

Метод объявляют через двоеточие: function Enemy:takeDamage(amount). Двоеточие незаметно добавляет первый аргумент self — сам объект. Вызывают тоже через двоеточие.

Конструктор по традиции называют new: он создаёт таблицу с полями и привязывает к ней метатаблицу класса.

  • Enemy.__index = Enemy — типовая строка, без неё методы не найдутся
  • Точка вместо двоеточия при вызове метода — и self окажется первым аргументом
  • Классы обычно живут в ModuleScript
  • Не наследуй всё подряд: в игровом коде композиция чаще проще

Пример

Класс врага с здоровьем и уроном.

ReplicatedStorage/Enemy.lua
  1. local Enemy = {}
  2. Enemy.__index = Enemy
  3.  
  4. function Enemy.new(name: string, health: number)
  5. local self = setmetatable({}, Enemy)
  6.  
  7. self.name = name
  8. self.health = health
  9.  
  10. return self
  11. end
  12.  
  13. function Enemy:takeDamage(amount: number)
  14. self.health = math.max(0, self.health - amount)
  15.  
  16. if self.health == 0 then
  17. print(self.name .. " повержен")
  18. end
  19. end
  20.  
  21. return Enemy

Задача

Сделай класс Chest: у сундука есть содержимое и признак «открыт». Метод open возвращает содержимое и помечает сундук открытым, повторное открытие возвращает nil.

  • Признак храни прямо в self
  • Проверку «уже открыт» делай в начале метода
Показать решение
ReplicatedStorage/Chest.lua
  1. local Chest = {}
  2. Chest.__index = Chest
  3.  
  4. function Chest.new(loot: string)
  5. local self = setmetatable({}, Chest)
  6.  
  7. self.loot = loot
  8. self.opened = false
  9.  
  10. return self
  11. end
  12.  
  13. function Chest:open(): string?
  14. if self.opened then
  15. return nil
  16. end
  17.  
  18. self.opened = true
  19.  
  20. return self.loot
  21. end
  22.  
  23. return Chest

Проверь себя

Что делает поле __index в метатаблице?

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

__index — правило поиска: не нашли в объекте, идём в класс.

Чем отличается вызов obj:method() от obj.method()?

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

Двоеточие — сокращение для передачи self, точка этого не делает.