ulua的简单解析,cs和Lua的相互调用
热更新是unity一个长久的话题,热更新主要有两部分,一部分就是资源,这个靠u3d的assetbundle就可以做,另一部分就是逻辑了。游戏更新难免会遇到一些流程或者UI的逻辑变动。在PC和Android上可以使用C#的反射来动态的生成代码,而IOS的Full AOT(完全 预先编译/静态编译)的性质,因此这个办法在IOS上使用不了。为了解决这个问题,我们引入了Lua。使用Lua的主要原因是因为Lua在Unity是当作文本资源使用的,Lua在Unity中的执行是依赖于解释器(虚拟机)读取Lua代码进行解释执行。所以工程中比较常变化的逻辑代码都是写在Lua中,通过更新Lua(文本文件)来实现逻辑的热更,而常用的热更新方案有sLua,xLua,uLua等等。公司这里使用的是ulua,因此今天就来初步解析并使用下uLua。为了方便学习,本文章使用的是SimpleFramework_NGUI_v0.4.1,这个集成了NGUI,uLua的框架。
1.简单认识uLua
uLua具体怎么去调用Lua的,怎么让Lua调用C#这里先不做具体研究,先简单地使用起来,不去探究原理了。我们先认识下uLua中的几个类,让我们不至于使用得不明不白。当然如果想要直接使用,则可以跳过这个部分。
(1)WrapFile.cs
WrapFile类的内容很简单,就是保存了一个需要生成Wrap的数组(binds)。通过_GT()方法来获取类的信息并标记类的类型。如果我们用C#写了个类想要在Lua中使用,可以在binds中添加
(2)BindLua.cs
BingLua.cs类里主要是uLua对Unity菜单栏的一些扩展。里面有一些批处理方法,比如Lua/Gen Lua Wrap Files实际上是调用了Binding()方法。这个方法用来遍历WrapFil里的binds数组,来生成相应的Wrap文件。而里面调用的GenLuaBinder()方法用来生成Wrap.lua和LuaBinder.cs。GenLuaDelegates()方法用来生成DelegateFactory.cs。
(3)Wrap.lua
Wrap.lua使用了”import 类名”把类注册到lua中,import字段是在Lua.cs的LuaState()方法来绑定到lua的全局表中,并且用来调用LuaStatic.importWrap()方法。因为我们要调用Lua时一般会用用到LuaScriptMgr.cs。在New LuaScriptMgr()时,则会自动调用LuaState()方法来绑定一些全局的字段。
(4)LuaBinder.cs
LuaBinder.Bind()方法则是用来把Wrap.lua里的类和相应的Wrap类,通过Wrap类的Register()方法来进行绑定。
(5)DelegateFactory.cs
大致和LuaBinder类似,用来注册委托。
这样我们就知道通过Unity的菜单栏,uLua为我们做了什么事。我们该如何简单的使用uLua,下面我来演示一下。
2.简单使用uLua
首先,把AppConst.cs中的DebugMode设置为true,这是框架的设置。意思是我们会在Unity编辑器下来运行程序,而不是打包到具体平台上使用。当DebugMode为true时会读取工程的Lua文件夹来获取Lua文件。 以后如果需要导出具体平台上的包则需要通过Game/Build xxx Resource 他会根据不同平台把lua和资源生成到相应的文件夹下。
我们先写一个cs用来注册到Lua中:
|
|
这里有一个坑,我们写的这个类不能继承MonoBehaviour。因为继承了MonoBehaviour的类不能使用构造函数来创建对象,只能用AddComponent()来创建对象。而uLua是通过把注册到Lua中的类所有的构造方法绑定为New来创建对象的。如果从Unity中新建的脚本记得把MonoBehaviour删去。
再写一个Lua文件LuaTest.lua,用来在Lua中调用我们写的testprint()方法:
|
|
写一个类用来运行调用这个lua文件 StartTest.cs:
|
|
接下来打开WrapFile.cs,仿照着把CsToLuaTest写进binds中。在菜单栏中点击Lua/Clear LuaBinder + Wrap Files。这是清除之前已经生成的文件。然后再点击Lua/Gen Lua Wrap Files。这样就能生成Wrap文件并在Lua中进行注册了。 把StartTest绑到场景中的物体上,运行游戏。就能看到我们在LuaTest.lua成功调用了CsToLuaTest.cs中的testprint()方法并打出了success的日志。