由于咱们在前面已经花了大量的时间来学习lua,因此咱们在本节就会结束xlua的部分。c++
2.3更轻量的by value方式:映射到dictionary<>,list<>。不想定义class或者interface的话,咱们能够考虑用这个,前提table下key和value的类型都是一致的。c#
Dictionary<string, object> dict = luaenv.Global.Get<Dictionary<string, object>>("person"); foreach (string key in dict.Keys) { print(key + "-" + dict[key]); }
这个就是经过dictionary的方式来完成的,不过它有一个注意点是它只能输出有键值对的table,其余的形式它是映射不出来的。那么咱们应该若是去解决这个问题呢?这里就要用到的是list<>了,可是这个集合也有一个要注意的是它只能映射数组类型的table,因此咱们须要将二者相结合来使用,下面是list的代码:数组
List<object> listTxt = luaenv.Global.Get<List<object>>("person"); foreach (object o in listTxt) { print(o); }
2.4另一种方式 by ref方式:映射到luatable类 这种方式的好处也不须要生成代码,但也有一点问题,比较慢。咱们不建议使用这种方式,建议使用第二种方式。其实这种方式是插件帮咱们写好的,咱们只须要直接调用就好了,代码以下:安全
LuaTable tab = luaenv.Global.Get<LuaTable>("person"); print(tab.Get<string>("name"));
这四种方式咱们已经所有介绍了一遍,咱们发现其实他们用的都是同一个方法luaenv.Golbal.Get<T>("name")的形式,这也就说明了xlua的方便性,咱们只须要简单的建立xlua虚拟机就好了,这样大大的节约了时间,加快代码的效率。函数
3、访问一个全局的function性能
咱们如今发现xlua只用一个Get,可是不一样的是类型映射。学习
1.映射到delegate ui
这种方式是建议的方式,性能好不少,并且类型安全。缺点是要生成代码。在这里首先要回顾一下delegate,由于在如今这个阶段我用的比较少,因此有点忘记了,有必要再去看看。lua
c#中的委托(delegate)相似c或c++中函数的指针。委托(delegate)是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。委托(delegate)特别用于实现事件和回调函数。全部的委托(delegate)都派生自system.delegate类。上面说delegate能够理解成指针。咱们把delegate实例化出来后,就能够给里面传递一个方法,这样就是间接的引用了,因此咱们写下以下的代码:spa
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 委托 { delegate int NumberChanger(int n); class Program { static int num = 10; public static int AddNum(int p) { num += p; return num; } public static int MultNum(int q) { num *= q; return q; } public static int GetNum() { return num; } static void Main(string[] args) { //建立委托实例 NumberChanger nc1 = new NumberChanger(AddNum); NumberChanger nc2 = new NumberChanger(MultNum); //使用委托对象调用方法 nc1(25); Console.WriteLine("Value of Num:{0}", GetNum()); nc2(25); Console.WriteLine("value of Num:{0}", GetNum()); Console.ReadKey(); } } }
nc1(24)虽然是给委托赋值的,可是nc1是引用AddNum()这个方法的,委托会调用这个方法,这实际上就是一种引用。通过咱们这样的梳理,咱们就不会对委托产生迷茫了。好了咱们继续刚才的话题。
在这里咱们有一个问题,若是lua中的函数有返回值怎么办呢?lua中是能够返回多个返回值的,而c#只能返回一个返回值,咱们看下面的代码:
Add add = luaenv.Global.Get<Add>("method"); int resa;int resb; int res=add(34, 67,out resa,out resb); print(res+" "+resa + " " + resb); add = null; luaenv.Dispose(); } [CSharpCallLua] delegate int Add(int a, int b,out int resa,out int resb);
使用out就好了,咱们就能解决返回值不一致的问题。效果以下:
2.映射到LuaFunction这种凡是的优缺点恰好和第一种相反。使用也简单,LuaFunction上有个变参的call函数,能够传递任意类型,任意个数的参数,返回值是object的数组,对应于lua的多返回值。
LuaFunction func = luaenv.Global.Get<LuaFunction>("method"); object[] os = func.Call(1, 2); foreach (object o in os) { print(o); }
Lua调用从C#
本部分也是比较简单的。咱们只说两个部分。废话很少说,咱们就向下看吧。
1.new C#对象
咱们建立一个txt文件LuaCallCSharp.lua.txt 在里面写CS.UnityEngine.GameObject() 在C#中咱们写
LuaEnv luaenv = new LuaEnv();
luaenv.DoString("require 'LuaCallCSharp'");
luaenv.Dispose();
这样就会在unity中建立一个gameobject了。
2.Lua访问c#中成员属性和方法
local gameObject=CS.UnityEngine.GameObject local camera=gameObject.Find("Main Camera") camera.name="666" local Cam01=camera:GetComponent("Camera") gameObject.Destroy(Cam01)
这样写的效果就是将unity中的Main Camera的名字改为666,并将Main Camera身上的Camera给禁用掉。这样就能完成lua对c#的访问。好了,全部的xlua内容今天所有完成了,咱们在下一节的时候,将会用xlua开发一个案例,一块儿学习吧。