Использование Lua скриптов в .NET с LuaInterface

от автора

Привет, Хабрахабр!

Этот небольшой пост родился после того, как я решил узнать, как можно запускать скрипты Lua совместно с игрой на C# (либо на другом .NET-языке). с использованием библиотеки LuaInterface. Я был впечатлен легкостью этого интерфейса по сравнению с lua.h на C++

image

Что нужно знать

C# на приличном уровне, иметь понятие об основах программирования, а также о подключении ссылок в проекте на Visual Studio

Начало

Исходники (со всеми dll, конечно) выложены в конце поста

Первое, что нужно сделать — подключить к нашему проекту LuaInterface.dll. Просто добавляем ссылку на файл .dll. Если вы еще не в курсе, как это делается, то можете найти мануалы в интернете. Также для подключения требуется luanet.dll

Небольшой ликбез

LuaInterface — библиотека для удобной интеграции между Lua и CLR
Lua — очень легкий скриптовый язык программирования. Вот его разбор
Для чего нужны скрипты — выдержка из другого моего поста

Скрытый текст

Если вы разрабатывали большие проекты (к примеру, масштабные игры), замечали, что с каждой новой сотней строк кода компиляция идет медленней?
В игре создается больше оружия, больше диалогов, больше меню, больше etc.
Одна из самых главных проблем, возникающих в связи с нововведениями — поддерживать бессчетное множество оружия и бейджиков довольно сложное занятие.
В ситуации, когда просьба друга/босса/напарника изменить диалог или добавить новый вид оружия занимает слишком много времени, приходится прибегать к каким-то мерам — например, записи всей этой фигни в отдельные текстовые файлы.
Почти каждый геймдевелопер когда-нибудь делал карту уровней или диалоги в отдельном текстовом файле и потом их считывал. Взять хотя бы простейший вариант — олимпиадные задачи по информатике с файлом ввода

Но есть способ, на голову выше — использование скриптов.

Решение проблемы

«Окей, для таких дел хватает обычного файла с описанием характеристиков игрока. Но что делать, если в бурно развивающемся проекте почти каждый день приходится немножко изменять логику главного игрока, и, следовательно, много раз компилировать проект?»
Хороший вопрос. В этом случае нам на помощь приходят скрипты, держащие именно логику игрока со всеми характеристиками либо какой-либо другой части игры.
Естественно, удобнее всего держать, логику игрока в виде кода какого-нибудь языка программирования.
Первая мысль — написать свой интерпретатор своего скриптового языка, выкидывается из мозга через несколько секунд. Логика игрока определенно не стоит таких жутких затрат.
К счастью, есть специальные библиотеки скриптовых языков для С++, которые принимают на вход текстовый файл и выполняют его.

Об одном таком скриптовом языке Lua пойдет речь.
Если вы разрабатывали большие проекты (к примеру, масштабные игры), замечали, что с каждой новой сотней строк кода компиляция идет медленней?
В игре создается больше оружия, больше диалогов, больше меню, больше etc.
Одна из самых главных проблем, возникающих в связи с нововведениями — поддерживать бессчетное множество оружия и бейджиков довольно сложное занятие.
В ситуации, когда просьба друга/босса/напарника изменить диалог или добавить новый вид оружия занимает слишком много времени, приходится прибегать к каким-то мерам — например, записи всей этой фигни в отдельные текстовые файлы.
Почти каждый геймдевелопер когда-нибудь делал карту уровней или диалоги в отдельном текстовом файле и потом их считывал. Взять хотя бы простейший вариант — олимпиадные задачи по информатике с файлом ввода

Но есть способ, на голову выше — использование скриптов.

Решение проблемы

«Окей, для таких дел хватает обычного файла с описанием характеристиков игрока. Но что делать, если в бурно развивающемся проекте почти каждый день приходится немножко изменять логику главного игрока, и, следовательно, много раз компилировать проект?»
Хороший вопрос. В этом случае нам на помощь приходят скрипты, держащие именно логику игрока со всеми характеристиками либо какой-либо другой части игры.
Естественно, удобнее всего держать, логику игрока в виде кода какого-нибудь языка программирования.
Первая мысль — написать свой интерпретатор своего скриптового языка, выкидывается из мозга через несколько секунд. Логика игрока определенно не стоит таких жутких затрат.
К счастью, есть специальные библиотеки скриптовых языков для С++, которые принимают на вход текстовый файл и выполняют его.

Об одном таком скриптовом языке Lua пойдет речь.

Теперь, когда у нас есть проект с подключенным LuaInterface, переходим к коду!

LuaInterface — основы

В основном .cs файле пишем

using LuaInterface; 

Основной класс этой библиотеки — Lua

Lua lua = new Lua(); 

Объявление констант

Очень просто можно объявить константы. Делается это так

lua[ключ] = значение; 

lua["version"] = 0.1; lua["name"] = "YourName"; lua["test"] = 200; lua["color"] = new Color(); lua["my"] = this; 

В качестве значения может выступать что угодно — число, строка, даже классы и структуры (о том, как с ними работать, будет дальше)

Регистрация функций

В Lua можно зарегистрировать функцию из C#

lua.RegisterFunction(название функции в Lua, this, функция); 

lua.RegisterFunction("puts", this, typeof(Program).GetMethod("Test")); 

Регистрация классов и структур

Одна из самых приятных сторон LuaInterface, которая может удивить тех, кто использует Lua совместно с C++, это то, что можно регистрировать объект класса и после этого вызывать в скрипте разные функции «напрямую»
То есть можно сделать так:

C#

    class LuaDebug     {         // Запись любого текста с указанным цветом         private void Print(string message, ConsoleColor color)         {             Console.ForegroundColor = color;             Console.WriteLine(message);         }          public void Log(string message)         {             Print("Log: " + message, ConsoleColor.White);         }          public void Warning(string message)         {             Print("Warning: " + message, ConsoleColor.Yellow);         }          public void Error(string message)         {             Print("Error: " + message, ConsoleColor.Red);         }          public string ConsoleRead()         {             return Console.ReadLine();         }     }  // ...  lua["Debug"] = new LuaDebug(); 

И после этого сделать Lua скрипт с таким содержанием:

str = Debug:ConsoleRead() -- считывание строки Debug:Log("Приложение запущено") Debug:Warning("Введенная строка: " .. str) Debug:Log("Удачного дня!") Debug:ConsoleRead() -- пауза 

Выполнение Lua кода

Выполнить Lua код (со всеми зарегистрированными функциями и константами) можно двумя способами
Первый — прямиком из C#

lua.DoString(код) 

lua.DoString("Debug:Log('Hello, Habr!')" + "\n" +       "Debug:ConsoleRead()"); 

Второй — из файла

lua.DoFile(file) 

lua.DoFile("script.lua") 

(Оба метода возвращают значение object[] — это то, что возвращает Lua скрипт после выполнения)

Обработка исключений

Для обработки исключений — ошибок, которые могут выскочить во время выполнения скрипта, следует использовать LuaException err

            try             {               // Lua, lua, lua             }             catch (LuaException err)             {                // Обработка ошибки             } 

Вызов методов из Lua

Для вызова метода из Lua надо выполнить скрипт, выудить метод, и выполнять его когда потребуется.
Пример

lua.DoFile("file.lua") LuaFunction func = lua["func"] as LuaFunction; // function func() {...} end func.Call(); 

Также в Call(params object[] args) можно передавать входные параметры для функции
Тот же финт срабатывает и со значениями, только вместо LuaFunction используем string, int, double и так далее

Дополнительные материалы

  • Для таблиц в LuaInterface предусмотрен класс LuaTable, регистрируется в объекте класса Lua он как обычная переменная, а запись переменных в саму таблицу мало чем отличается от записи переменных в самом Lua объекте
  • Также есть класс LuaDLL, используемый для «низкоуровневой» работы с Lua (из lua.h). Толку от него немного, и вряд ли кто-то использует его по-серьезному
    Пример
                LuaDLL.lua_open();             LuaDLL.lua_createtable(luaState, 1, 1); 

image
Символика Lua

image
Love2D — один из самых популярных движков на Lua

image
Мод для Minecraft на Lua

image
https://bitbucket.org/Izaron/luaforhabr/src
Исходный код

ссылка на оригинал статьи http://habrahabr.ru/post/197262/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *