
《Garry's Mod》GLua 编程入门指南 简介 大家好!今天我们来了解一种新的编程语言——Lua,以及它在《Garry's Mod》这款游戏中的修改版本,即 GLua。 本指南是我的其他编程指南系列之一。 为什么要学习 Lua?原因很简单!《Garry's Mod》的大多数模组都是用 Lua 编写的,掌握这门编程语言后,你就能为该游戏创建自己的脚本和模组了!本指南的存在得益于活跃的Steam社区支持。同时,我也想感谢所有曾评价过我过往指南的人,感谢你们对我和我的指南的支持。
Lua 入门 正如我之前所说,GLua 是编程语言 Lua 的修改版本,专门为《盖瑞模组》(Garry's Mod,GMod)适配。它允许为游戏创建插件、脚本和修改内容,从而扩展游戏功能并添加新特性。开发环境 我们将直接在《盖瑞模组》中编写和运行代码,为此我们需要从Steam创意工坊获取2个扩展: EasyChat - 适用于《盖瑞模组》的增强型聊天工具,Lua Code Editor扩展正是在此工具中运行。 Lua Code Editor - 用于在《盖瑞模组》中直接编写和运行代码的界面。 订阅这些插件后,启动《盖瑞模组》并加载任意地图即可。当你打开聊天窗口时,它很可能与你习惯的不同(当然,如果你以前使用过这个扩展程序则除外)

*聊天界面* Lua代码编辑器会添加一个Lua标签页,请切换到该标签页。 要开始编写代码,请创建新文件,在Lua标签页中点击左上角的“文件”按钮,然后点击“新建”。

之后您将能够编写代码。若要运行代码,请点击此按钮:(绿色三角形)

第一个程序 和往常一样,我们不会立刻深入 Lua 语言的语法和细节,首先只需编写一个能在控制台输出“Hello world!”的脚本。 请改写或粘贴以下代码: print("Hello world!") 之后,运行该脚本。 当你运行它时,在控制台(通常会在 ~ 位置打开)中你将看到这条消息:

如果脚本已运行,且你在控制台中看到了消息,那么恭喜你,你写出了自己的第一个脚本!
Основы Lua Перед изучение GLua, мы сначала изучим основы Lua. Переменные и Типы ДанныхПеременныеПеременные - ячейки памяти, в которых мы можем хранить данные, модифицировать и использовать эти данные. В Lua переменные могут быть глобальными или локальными. Глобальные переменные доступны из любой части кода. Локальные переменные ограничены блоком кода, в котором они объявлены. (к примеру в функциях)Пример: -- Глобальная переменная myGlobalVar = 10 -- Локальная переменная local myLocalVar = 5 print(myGlobalVar) -- Вывод в консоль: 10 print(myLocalVar) -- Вывод в консоль: 5 "--" это комментарий, он не на что не влияет, там можно оставлять заметки. Рекомендация: Используйте локальные переменные (local), чтобы избежать конфликтов и повысить производительность, так как обращение к локальным переменным быстрее, чем к глобальным. Типы ДанныхLua имеет несколько основных типов данных: nil: Отсутствие значения. boolean: true или false. number: Числа (дробные и целые). string: Строки текста. function: Функции. table: Таблицы (ассоциативные массивы, аналог объектов). userdata: Необычные типы данных, обычно используемые в GLua. thread: Потоки.Примеры: local myNil = nil local myBool = true local myNumber = 42 local myString = "Hello, Lua!" local myFunction = function() print("Function") end local myTable = {key = "value", anotherKey = 123} ОператорыLua поддерживает различные операторы для выполнения операций над данными. Арифметические операторы (простая математика): + : Сложение - : Вычитание * : Умножение / : Деление % : Остаток от деления ^ : Возведение в степень Пример: local a = 10 local b = 3 print(a + b) -- 13 print(a - b) -- 7 print(a * b) -- 30 print(a / b) -- 3.3333 print(a % b) -- 1 print(a ^ b) -- 1000 P.s. Остаток от деления - это дробная часть, оставшаяся после деления чисел. К примеру мы делим 10 на 3, и получается 3.333... и .333 и есть остаток от деления. Логические операторы Работает над двумя переменными. and : Логическое "и" or : Логическое "или" not : Логическое "не" Пример: local x = true local y = false print(x and y) -- false print(x or y) -- true print(not x) -- false Пояснение: Логическое И вернёт true, если обе переменные равны true, Логическое ИЛИ вернёт true, если хотя бы одна из них равна true, Логическое НЕ вернёт инвертированное значение, то есть, если было true, вернёт false, и false аналогично. Операторы сравнения Работает над двумя переменными. == : Равно ~= : Не равно < : Меньше > : Больше <= : Меньше или равно >= : Больше или равно Пример: local a = 5 local b = 10 print(a == b) -- false print(a ~= b) -- true print(a < b) -- true print(a > b) -- false print(a <= b) -- true print(a >= b) -- false Условные КонструкцииПозволяют выполнять код в зависимости от условий. В Lua есть 3 основные условные конструкции. if, elseif, else. Синтаксис: if условие1 then -- Код выполняется, если условие1 истинно elseif условие2 then -- Код выполняется, если условие2 истинно else -- Код выполняется, если все условия ложны end P.s. elseif и else не обязательные. Примеры: -- только if local x = 100 if x == 100 then print("Meow") end-- с elseif local x = 100 if x == 50 then print("Sus") elseif x == 100 then print("100x Meow") end-- с else и elseif local health = 75 if health == 100 then print("Здоровье в норме") elseif health ~= 100 and health > 50 then print("Надо полечиться") else print("Проблемы со здоровьем") end ЦиклыПозволяют повторять блок кода несколько раз. Цикл for Синтаксис: for инициализация, условие, шаг do -- Код end Пример: for i = 1, 5 do print("Итерация " .. i) end Вывод: Итерация 1 Итерация 2 Итерация 3 Итерация 4 Итерация 5 Цикл while Синтаксис: while условие do -- Код end Пример: local count = 1 while count <= 5 do print("Счетчик: " .. count) count = count + 1 end Вывод: Счетчик: 1 Счетчик: 2 Счетчик: 3 Счетчик: 4 Счетчик: 5 ФункцииФункции позволяют группировать код для повторного использования. Объявление и вызов функций Синтаксис: local function имяФункции(параметры) -- Код функции end -- Вызов функции имяФункции(аргументы) Пример: local function greet(name) print("Привет, " .. name .. "!") end greet("Dr. L") -- Вывод: Привет, Игрок! Функции с возвращаемыми значениями Пример: local function add(a, b) return a + b end local результат = add(5, 7) print(результат) -- Вывод: 12 ТаблицыТаблицы в Lua — это основной структурный тип данных, который может использоваться как массивы, словари (ассоциативные массивы) и даже объекты. Создание таблицы Пример: -- Таблица как массив local fruits = {"яблоко", "банан", "апельсин"} -- Таблица как словарь local player = { name = "Игрок", health = 100, armor = 50 } Доступ к элементам таблицы Пример: print(fruits[1]) -- Вывод: яблоко print(player["health"]) -- Вывод: 100 Добавление и изменение элементов Пример: -- Добавление элемента table.insert(fruits, "груша") -- Изменение значения player.health = 90 Перебор таблицы Пример: -- Перебор массива for index, fruit in ipairs(fruits) do print(index, fruit) end -- Перебор словаря for key, value in pairs(player) do print(key, value) end Вывод: 1яблоко 2банан 3апельсин 4груша nameИгрок health90 armor50 Минутка отдыха Предыдущая глава была О-О-О-ОЧЕНЬ большая, но это всего пол пути нашего изучения GLua. Мы изучили основы и синтаксис Lua, но нам так же нужно изучить основы GLua. Я решил сделать эту главу, чтобы вы могли посидеть и отдохнуть, так как нельзя слишком долго воспринимать кучу информации, иногда надо делать передышки. Как мне однажды говорили, сначала надо сфокусировать внимание читателя, потом дать ему отдохнуть и опять настроить на работу. Так что можете просто посмотреть на эту гифку и попить чай :)
Основы GLua Теперь мы будем изучать GLua! Надеюсь вы отдохнули, и готовы к изучению основных концепций GLua. GLua расширяет стандартные возможности Lua, предоставляя функции и объекты, специфичные для Garry's Mod. Здесь мы рассмотрим ключевые концепции. Все под-главы этой главы будут разделены в обычные главы, чтобы не нагружать одну главу. Хуки (Hooks) Хуки позволяют подключать свои функции к определённым событиям в игре. Это мощный инструмент для расширения функционала. На данной функции делается большинство пользовательских интерфейсов, да и в целом модификаций. Основные хуки Think: Вызывается каждый кадр. HUDPaint: Используется для отрисовки на экране. PlayerInitialSpawn: Срабатывает, когда игрок впервые присоединяется к серверу. EntityTakeDamage: Срабатывает, когда сущность получает урон. Использование хуков Синтаксис: hook.Add("ИмяХука", "УникальныйИдентификатор", function(аргументы) -- Код end) Пример: hook.Add("PlayerInitialSpawn", "WelcomeMessage", function(ply) ply:PrintMessage(HUD_PRINTTALK, "Добро пожаловать на сервер, " .. ply:Nick() .. "!") end) Объяснение: hook.Add: Функция для добавления хука. "PlayerInitialSpawn": Имя хука, к которому подключаемся. "WelcomeMessage": Уникальный идентификатор хука. Используется для последующего удаления хука, если необходимо. function(ply): Функция, которая будет вызвана при срабатывании хука. В данном случае принимает игрока ply как аргумент.Удаление хуков Синтаксис: hook.Remove("ИмяХука", "УникальныйИдентификатор") Пример: hook.Remove("PlayerInitialSpawn", "WelcomeMessage") Подробнее про хуки: -- Think (выполняется каждый кадр) hook.Add("Think", "MyThinkHook", function() -- Код здесь выполняется каждый кадр end) -- Initialize (выполняется при загрузке скрипта) hook.Add("Initialize", "MyInitHook", function() print("Скрипт загружен!") end) -- PlayerInitialSpawn (когда игрок впервые присоединяется) hook.Add("PlayerInitialSpawn", "MySpawnHook", function(ply) print(ply:Nick() .. " присоединился к серверу!") end) -- Использование клавиш hook.Add("PlayerButtonDown", "MyButtonHook", function(ply, button) if button == KEY_F then print(ply:Nick() .. " нажал F") end end) -- Получение урона hook.Add("EntityTakeDamage", "MyDamageHook", function(target, dmginfo) if target:IsPlayer() then print(target:Nick() .. " получил " .. dmginfo:GetDamage() .. " урона") end end) -- Использование чата hook.Add("PlayerSay", "MyChatHook", function(ply, text, team) if string.lower(text) == "!help" then ply:ChatPrint("Это помощь!") return "" -- Предотвращает отображение команды в чате end end) -- Отрисовка после основных объектов hook.Add("PostDrawOpaqueRenderables", "My3DRenderHook", function() cam.Start3D() for _, ply in ipairs(player.GetAll()) do local pos = ply:GetPos() render.DrawWireframeSphere(pos, 32, 16, 16, Color(255, 0, 0)) end cam.End3D() end) -- Отрисовка эффектов hook.Add("RenderScreenspaceEffects", "MyEffectHook", function() local tab = { ["$pp_colour_addr"] = 0, ["$pp_colour_addg"] = 0, ["$pp_colour_addb"] = 0, ["$pp_colour_brightness"] = 0, ["$pp_colour_contrast"] = 1, ["$pp_colour_colour"] = 0.5, ["$pp_colour_mulr"] = 0, ["$pp_colour_mulg"] = 0, ["$pp_colour_mulb"] = 0 } DrawColorModify(tab) end) Работа с Сущностями (Entities) Сущности — это объекты в мире игры, такие как игроки, NPC, пропсы и т.д. Создание сущностиПример: Создание пропа local function CreateProp() local prop = ents.Create("prop_physics") if not IsValid(prop) then return end prop:SetModel("models/props_c17/oildrum001.mdl") prop:SetPos(Vector(0, 0, 100)) prop:Spawn() end hook.Add("PlayerInitialSpawn", "SpawnPropOnJoin", function(ply) CreateProp() end) Объяснение: ents.Create: Создаёт новую сущность указанного класса. IsValid: Проверяет, была ли сущность успешно создана. SetModel: Устанавливает модель сущности. SetPos: Устанавливает позицию сущности в мире. Spawn: Спавнит сущность в мире. Поиск сущностейПримеры: Поиск по классу: local props = ents.FindByClass("prop_physics") for _, prop in ipairs(props) do print(prop:GetModel()) end Поиск в радиусе: local entities = ents.FindInSphere(Vector(0, 0, 0), 500) for _, ent in ipairs(entities) do print(ent:GetClass()) end Консольные команды С помощью данной функции вы сможете создавать свои консольные команды! Синтаксис -- Простая команда concommand.Add("mycommand", function(ply, cmd, args) print("Команда выполнена!") end) -- Команда с аргументами concommand.Add("say_hello", function(ply, cmd, args) local name = args[1] or "noname" -- если имя не указано, то заменяет его на noname print("Привет, " .. name .. "!") end) После того, как вы запустите этот код, в консоли появятся созданные вами команды! Основные функции отрисовки Текст-- Простой текст draw.SimpleText( "Текст", -- текст "DermaDefault", -- шрифт 100, -- x позиция 100, -- y позиция Color(255,255,255),-- цвет TEXT_ALIGN_LEFT, -- горизонтальное выравнивание TEXT_ALIGN_TOP -- вертикальное выравнивание ) -- Текст с тенью draw.SimpleTextOutlined( "Текст с тенью", -- текст "DermaDefault", -- шрифт 100, -- x позиция 100, -- y позиция Color(255,255,255),-- цвет текста TEXT_ALIGN_LEFT, -- гориз. выравнивание TEXT_ALIGN_TOP, -- верт. выравнивание 1, -- толщина обводки Color(0,0,0) -- цвет обводки ) Примитивы-- Прямоугольник surface.SetDrawColor(255, 0, 0) -- красный цвет surface.DrawRect(x, y, width, height) -- Линия surface.DrawLine(x1, y1, x2, y2) -- Полигон surface.DrawPoly({ {x = 100, y = 100}, {x = 200, y = 100}, {x = 150, y = 200} }) Изображения и текстуры-- Загрузка материала local myMaterial = Material("path/to/material.png") -- Отрисовка материала surface.SetMaterial(myMaterial) surface.SetDrawColor(255, 255, 255) surface.DrawTexturedRect(x, y, width, height) -- Отрисовка повернутого материала surface.DrawTexturedRectRotated(x, y, width, height, angle) Интерактивные элементыlocal function IsMouseOver(x, y, w, h) local mouseX, mouseY = gui.MousePos() return mouseX >= x and mouseX <= x + w and mouseY >= y and mouseY <= y + h end hook.Add("HUDPaint", "DrawInteractiveButton", function() local x, y = 100, 100 local w, h = 200, 50 -- Проверка наведения мыши local isHovered = IsMouseOver(x, y, w, h) -- Изменение цвета при наведении surface.SetDrawColor(isHovered and Color(100, 100, 255) or Color(50, 50, 255)) surface.DrawRect(x, y, w, h) -- Текст кнопки draw.SimpleText( "Нажми меня!", "DermaDefault", x + w/2, y + h/2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER ) end) -- Обработка клика hook.Add("GUIMousePressed", "HandleButtonClick", function(mouseCode) if mouseCode == MOUSE_LEFT then local x, y = 100, 100 local w, h = 200, 50 if IsMouseOver(x, y, w, h) then print("Кнопка нажата!") end end end HUD (Heads-Up Display) HUD - это наш интерфейс, в котором отображается здоровье, броня и тд. Его можно изменить, или полностью переделать! Все это делается через хуки, а конкретнее, через хук HUDPaint. Несколько примеров Базовый HUD-- Простой HUD с здоровьем hook.Add("HUDPaint", "MySimpleHUD", function() local ply = LocalPlayer() if not IsValid(ply) then return end -- Параметры local health = ply:Health() local armor = ply:Armor() local screenW = ScrW() local screenH = ScrH() -- Отрисовка здоровья draw.SimpleText( "HP: " .. health, "DermaLarge", screenW * 0.1, screenH * 0.9, Color(255, 0, 0), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER ) -- Отрисовка брони draw.SimpleText( "AP: " .. armor, "DermaLarge", screenW * 0.1, screenH * 0.95, Color(0, 0, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER ) end) Давайте разберём его по частям! hook.Add("HUDPaint", "MySimpleHUD", function() - хук отрисовки дисплея. local ply = LocalPlayer() - объект нашего персонажа. if not IsValid(ply) then return end - просто проверка, чтобы не было ошибок. draw.SimpleText(...) отрисовывает текст. Видеоролики Здесь представлены несколько видеороликов на Youtube, по программированию на GLua. Плейлист (Англ)Автор: Omni Games https://www.youtube.com/watch?v=qkPjxGsDYPw&list=PLLAN7OC4G99RNqy_RY8s5-V-nA8RBh1cn Видео (Англ)Автор: Code Blue https://www.youtube.com/watch?v=c1mQ3mpdiJU Советы: Практикуйтесь регулярно: Чем больше вы пишете код, тем лучше понимаете язык. Читайте документацию: Официальная документация — лучший источник информации. Изучайте чужой код: Это поможет вам узнать новые методы и подходы. Участвуйте в сообществах: Общение с другими разработчиками ускорит ваш прогресс. Не бойтесь ошибок: Ошибки — это часть процесса обучения. Используйте их для улучшения своих навыков.
结束 这份指南非常长,但希望您能喜欢 :) 本指南还将不断修改、补充等等。 也许这份指南还不太完善,希望您能在评论中指出问题。感谢您阅读本指南。祝您在学习编程语言和编写脚本时一切顺利!
其他指南: https://steamcommunity.com/sharedfiles/filedetails/?id=3401446439 https://steamcommunity.com/sharedfiles/filedetails/?id=3395692013 https://steamcommunity.com/sharedfiles/filedetails/?id=3390154519 https://steamcommunity.com/sharedfiles/filedetails/?id=3397931731 https://steamcommunity.com/sharedfiles/filedetails/?id=3389441554
2026-02-11 14:01:05 发布在
Garry's Mod
说点好听的...
收藏
0
0
