Unity热更新技术学习——LuaInterface

文章目录

    • 概述
    • 使用LuaInterface
    • LuaInterface教程
        • 类型转化
        • 从CLR访问Lua
        • 从Lua访问CLR

概述

LuaInterface是一个CLR库,以 .dll 的形式呈现。

要想在Unity中使用Lua,必须解决C#和Lua的交互问题,或者说CLR(即windows平台为人熟知的.Net或者linux上的Mono)和Lua的交互。LuaInterface为了解决这个问题,最重要的就是做了两件事情:

  • LuaInterface 允许Lua脚本实例化CLR对象并使用它,甚至创建新的CLR对象
  • 允许CLR应用程序使用LuaInterface嵌入一个Lua解释器,从而你可以通过书写lua代码扩展CLR应用程序

CLR通过平台调用(Platform/Invoke)技术将Lua解释器编译为一个动态链接库,然后使用的时候将之与CLR应用程序本身链接,这个动态链接库,就是LuaInterface。当然,解释器只是LuaInterface中的一部分。

想要了解什么是CLR,请参考:这里
想要了解什么是平台调用(P/Invoke)技术,请参考:这里

使用LuaInterface

LuaInterface下载:http://luaforge.net/projects/luainterface/

从上面的网站中找到最新的LuaInterface压缩包,解压,得到以下文件:
Unity热更新技术学习——LuaInterface_第1张图片
使用visual studio新建一个C#控制台程序,为其添加上述两个 dll 引用。
Unity热更新技术学习——LuaInterface_第2张图片
然后书写如下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LuaInterface;

namespace TestLuaInterface
{
    class Program
    {
        static void Main(string[] args)
        {
            Lua lua = new Lua(); // 实例化一个lua解释器

            lua["name"] = "chentianqin"; // 创建一个lua字符串
            lua["age"] = 23; // 创建一个lua数字
            lua.NewTable("people"); // 创建一个lua表

            lua.DoString(@"print('This is run by lua.DoString!!!')");
            lua.DoString(@"print(name)");
            lua.DoString(@"print(age)");
            lua.DoString(@"people[1] = 'Tom';print(people[1]);");

            object[] values = lua.DoString("return name, age");
            string name = (string)values[0];
            double age = (double)values[1];
            LuaTable table = (LuaTable)lua["people"];

            Console.WriteLine("\n********以下为C#层打印的东西********\n");
            Console.WriteLine("name = " + name);
            Console.WriteLine("age = " + age);
            Console.WriteLine("table = " + table[1]);

            Console.ReadLine();
        }
    }
}

点击运行,如果报System.IO.FileLoadException:"混合模式程序集...的错误,请为App.config文件里面的startup添加useLegacyV2RuntimeActivationPolicy属性。


<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true"> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    startup>
configuration>

程序输出如下:
Unity热更新技术学习——LuaInterface_第3张图片
在上面例子中,我们做了以下几件事情:

  • 实例化了一个lua解释器,帮助我们运行lua代码
  • 使用解释器实例的索引器在C#层创建lua对象,包括字符串,数字和lua表
  • 使用lua.DoString()方法执行一段lua源码,并获得它的返回(如果源码中有return语句的话)

为此,我们已经见识到了LuaInterface如何完美地运作了。当然,LuaInterface不止如此。

LuaInterface教程

正如上面所述,LuaInterface为了解决Lua和CLR的交互完成了两件事情:允许从CLR访问Lua,以及允许从Lua访问CLR。

下面来看看这两件事情具体是如何运用的。不过在此之前,我们还需要搞清楚,这两种不同语言之间的变量类型是如何映射的。

类型转化

C#类型 Lua类型
null nil
System.Double numbers
System.String strings
System.Boolean booleans
LuaTable table
LuaFunction function
LuaUserData userdata

从CLR访问Lua

正如上面的示例代码一样:

Lua lua = new Lua(); // 创建一个Lua解释器实例

lua["num"] = 2; // 使用索引器去创建一个lua变量
lua["str"] = "a string";
lua.NewTable("tab"); // 使用NewTable()去创建一张lua表

double num = (double)lua["num"]; // 使用索引器去访问一个lua变量
string str = (string)lua["str"];

lua.DoFile("test.lua"); // 使用DoFile()去运行一个lua脚本
object [] rets = lua.DoString("return num, str;"); // 使用DoString()去执行一段lua源码

从Lua访问CLR

最新的LuaInterface(version >= 2.0.1)内置的解释器包含了一套库,里面自带一个全局的luanet模块。这个模块允许你加载CLR的程序集和CLR类型。

luanet.load_assembly("System.Windows.Forms") -- 使用load_assembly加载CLR程序集
luanet.load_assembly("System.Drawing")

Form=luanet.import_type("System.Windows.Forms.Form") -- 使用import_type导入CLR类型
Button=luanet.import_type("System.Windows.Forms.Button")
Point=luanet.import_type("System.Drawing.Point")

form1=Form() -- 导入之后就可以正常使用类型进行实例化和访问成员方法
button1=Button()
button2=Button()

function handleClick(sender,data)
 	if sender.Text=="OK" then -- 使用点句号 . 访问成员变量
    	sender.Text="Clicked"
  	else
    	sender.Text="OK"
  	end
  	button1.MouseUp:Remove(handler) -- 使用冒号 : 访问成员方法
  	print(sender:ToString())
end

button1.Text = "OK"
button1.Location=Point(10,10)
button2.Text = "Cancel"
button2.Location=Point(button1.Left, button1.Height + button1.Top + 10)
handler=button1.MouseUp:Add(handleClick) 
form1.Text = "My Dialog Box"
form1.HelpButton = true
form1.MaximizeBox=false
form1.MinimizeBox=false
form1.AcceptButton = button1
form1.CancelButton = button2
form1.Controls:Add(button1)
form1.Controls:Add(button2)
form1:ShowDialog()

这是一个官方的实例。将之保存为一个lua脚本,然后在C#里使用DoFile()方法执行它,你会得到如下结果:
Unity热更新技术学习——LuaInterface_第4张图片

你可能感兴趣的:(Unity游戏开发)