015-热更新之xlua语言二
Posted jake-caiee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了015-热更新之xlua语言二相关的知识,希望对你有一定的参考价值。
因为我们在前面已经花了大量的时间来学习lua,所以我们在本节就会结束xlua的部分。
2.3更轻量的by value方式:映射到dictionary<>,list<>。不想定义class或者interface的话,我们可以考虑用这个,前提table下key和value的类型都是一致的。
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虚拟机就行了,这样大大的节约了时间,加快代码的效率。
三、访问一个全局的function
我们现在发现xlua只用一个Get,但是不同的是类型映射。
1.映射到delegate
这种方式是建议的方式,性能好很多,而且类型安全。缺点是要生成代码。在这里首先要回顾一下delegate,因为在现在这个阶段我用的比较少,所以有点忘记了,有必要再去看看。
c#中的委托(delegate)类似c或c++中函数的指针。委托(delegate)是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。委托(delegate)特别用于实现事件和回调函数。所有的委托(delegate)都派生自system.delegate类。上面说delegate可以理解成指针。我们把delegate实例化出来后,就可以给里面传递一个方法,这样就是间接的引用了,所以我们写下如下的代码:
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开发一个案例,一起学习吧。
以上是关于015-热更新之xlua语言二的主要内容,如果未能解决你的问题,请参考以下文章