前言
以前使用U3D的Lua解决方案有XLua,现在UE使用的Lua的解决方案是UnLua,因此也对UnLua的源码进行了一定的阅读。
UnLua源码Git:https://github.com/Tencent/UnLua
以下是笔者自己的阅读过程,如何从外层开始阅读源代码。
既然要使用Lua,首先比较关心的是UE中怎么调用Lua,Lua中如何调用UE
UECallLua
首先从官方给的示例08开始
上图中给出了一个方法CallLuaByGlobalTable,发现17行是执行Lua字符串的地方,16行是在获得Lua的State。
跳转进来发现UnLuaBase.cpp中的GetState方法,继续跟踪GLuaCxt是什么?
发现GLuaCxt是在LuaContext.cpp中声明的。
那么他是在哪里初始化的呢?
通过跟踪GLuaCxt找到了他赋值和创建的地方。
发现在插件启动时StartupModule方法中创建,并马上注册了一些委托。
那到底注册了那些委托?
在注册的委托中发现了这样一个委托,看起来像是初始化的委托
发现其中调用了一个SetEnable方法,进入查看
这里可以看到,整个UnLua的初始化。
回到开始
上述我们知道了UnLua如何初始化,以及怎么在UE中调用Lua的了。
LuaCallUE
但是反过来Lua又是怎么调到UE的呢?Lua是在哪里启动的呢?入口又在什么地方?
先关注一下_G表是在哪里设置的
首先在示例中发现一个UnLua.lua的Lua脚本,并且大部分实例中都require了这个脚本,因此顺藤摸瓜
然后在UnLua.lua文件中发现了一些GetUProperty这些方法,那么这些方法是从哪里设置的呢。
其实在之前UE Call Lua的时候就已经出现过了
在LuaContext.cpp中的CreateState()看到这些是否似曾相识。 这就是在往_G表中注册相关的方法,可以看到GetUProperty赫然在列。
随便查看一个打Log的方法,其实就是在从LuaState中取参数,然后再转换为UE的类型,调用UE的方法进行打印。没什么神秘的。
因此这是在插件加载的时候就初始化好了一个Lua虚拟机,所有的代码都从这个入口进去。
总结
通过以上我们能够简单的清楚UE和Lua是怎么互相调用的,这也是使用这个插件最基础需要掌握。
思考:在这个基础上,Lua的数据类型和UE的数据类型是怎么互相转换的?