前置工作:创建好空的Unity工程并导入xLua中的Asset文件夹 (xLua下载地址)
在C#中使用xLua主要是通过XLua命名空间中的LuaEnv中的DoString去运行Lua代码,如下图所示:
再进一步,就是我们创建一个Resources文件夹,并在里面创建一个HelloWorld.lua.txt文件(这里后缀必须加上.txt才能让Unity和xLua的loader识别),然后在脚本里面读取这个文本文档里面的Lua代码并在Unity中运行,如下图所示:
当然,你也可以不放在Resources文件夹下,任意放到你喜欢的位置然后用IO读取里面的内容在运行,这部分不是这篇文章的重点,就不演示了。
上面的这种读取方法其实还不是最合适的。最合适的用法应该是调用Lua的loader去读取文件。因为xLua配置了一个从Resources中读取文件的loader,所以只要执行require语句,并传入文件名,对应的loader就会找到这个文件并运行里面的代码。注意,文件名后缀必须是.txt,这里在上面也有提到过。具体代码如下:
既然提到Loader,那就肯定要学习自定义loader。其实所谓的自定义Loader就是一个CustomLoader的委托,只要创建对应签名的方法,然后把这个方面作为参数添加到LuaEnv中,xLua就会在执行“require”时自动调用这些loader,直到返回值不为空为止。
下面是例子,我写了一个自己的loader,功能是从StreamingAssets这个文件夹中搜查读取目标文本文档,代码如下:
一、获取一个全局基本数据类型
访问LuaEnv.Global就可以了,上面有个模版Get方法,可指定返回的类型。
luaenv.Global.Get(“a”)
luaenv.Global.Get(“b”)
luaenv.Global.Get(“c”)
二、获取table类型对应到类和接口中
获取一个table就相对要麻烦一些,因为table可以被指定为C#多种数据结构,可以作为自定义的类去一一对应table的元素接受,也可以作为一个接口然后同样一一对应属性去接受等。
对于用类或者接口去接受table,有几点要注意:
代码如下:
这个是Lua文档,方便对照参考:
这里有一个地方要注意,当方法有参数时,第一个参数记得传一个占位参数代表是self,我这里随手写了个arg,用self或者任意东西都可以,自己理解就行。缺少这个占位参数,就会报错。
然后就是C#代码:
三、获取table类型对应到Dictonary和List中
用这两个数据结构去接受好处就是不需要创建新的数据结构,也比较简单。不过有一些地方需要注意:
四、获取全局function变量
1.委托
function在Lua中也是一种变量,因此也可以被接收,而C#虽然没有对应的变量,却可以用委托去接受。
对应的委托只要签名相同即可。只需注意一点,Lua中的方法可以有多个返回值,那么对应到C#中就要用out/ref参数去接受这些返回值。具体的自己试验一下就好,并没有什么难度。代码如下:
同时还要注意,在释放LuaEnv之前,要把我们获取到的委托引用清除掉才能执行lua.Dispose(),不然就会报错。
2.LuaFunction
如果要获取的方法调用不频繁,可以直接用这个类去直接接收而省去新建一个delegate的繁琐。不过这个方法性能损耗很大(还有上面没有提到的LuaTable),慎用。
调用LuaFunction.Call()可以传参,然后全部的返回值都会放到一个Object数组中,代码如下:
Lua中调用C# 我个人觉得官方留的教程文档就十分完善,所以我这里就对照着文档写了一些简单的调用例子并加上注释来当做演示,请打开官方XLua教程文档食用。
在那之前,我先提一下C#和Lua对于方法返回值和参数的不同处理。这里我写了一个对照样式,先是原本的C#方法,然后再往下是对应的Lua方法,上图:
首先看C# 方法,可以看到,该方法有2个常规参数,一个ref 参数,一个out参数,一个返回值。对应到Lua就是下图的方法:
可以看到,在Lua中参数有3个,返回值也是3个。这是因为在Lua中,C#的ref参数会同时被当做参数和返回值来处理;而out参数则不会被当做参数,仅仅当做返回值来对待。那么,Lua中的三个返回值就分别对应C#方法中的常规返回值和按顺序传入的ref和out参数。
全篇完,希望有帮到正在学习或者复习的各位同学,谢谢阅读!