ToLua框架支持直接读取运行lua脚本文件,也支持读取打包到.unity3d中的lua脚本。另外ToLua还支持字节码方式读取脚本。
打包工具类Packager.cs中对脚本的打包,选择如下打包方式:
注意此部分经过我的修改。然后它会调用下边部分:
上边选择了lua字节码方式,其实区别只是EncodeLuaFile函数会把lua脚本编译成可被luajit执行的格式文件。此函数内容如下:
无论是否选择字节码方式,最终生成的到临时目录Lua中的文件都是.byte结尾的。
ToLua/Lua和Lua目录下的脚本会拷贝到Lua目录下
我的工程目录结构如下:
临时目录下的结构如下:
对lua脚本的打包是把他们所在的文件夹打包,而不是每个lua文件分别打包,所以在遍历Lua目录后,还需要把Lua目录本身加入打包列表,因为它下边也包含脚本.
最终打包到StreamingAssets下的结构如下:
打包完资源后,BuildLuaFile()函数会生成一个luafiles文件,到StreamingAssets/lua中,内容如下:
BuildLuaFile函数的内容如下:
这个文件是用来干啥的呢?我们看一下LuaManager.cs中的代码:
此代码经过了我的修改,它的目的是读取luafiles中列出来的所有包含lua脚本的.unity3d文件,并加入到loader的字典中:
我们来看下LuaLoader.cs中的代码:
此代码经过了我的修改,注意上边转小写的目的是因为之前打包的时候,所有资源文件都被小写化了。
这里读取了所有脚本的bundle包,并组合了名称,保存到字典中,继续看AddSearchBundle函数:
那什么时候会使用到它们呢?我们来看LuaManager.cs中的调用:
继续进入:
此处我也做了修改,增加了bundleName参数,为什么增加这个参数后续会介绍。继续进入ReadFile
我选择了bundle方式,所以会执行下边函数,那上边的beZip是哪里设置的呢?看下边:
继续进入ReadZipFile:
这里是最关键的地方,只要是有luaState.DoFile的调用最终都会执行到这里
这里经过了我的修改,框架原来的代码只有fileName参数,而我们的资源包是以文件夹为单位的,所以想确定fileName(lua脚本名)到底属于哪个资源包是做不到的,
因此才会有原来的那种拼接字符串的无奈写法。
我这里增加了bundleName参数,在直接调用时,可以找到资源包,注意zipMap.TryGetValue这行。
但其实这里还有个问题,有的时候并不是主动调用DoFile才会到这个函数,比如初始化时,后续的子调用到达这里,这个时候bundleName参数是null的,所以我也保留了
原来的那种拼接方式,只是稍作修改,符合我luafiles文件中的文件名格式。这种方式能运行lua目录下和lua/fileName目录下的脚本。
之前还有个地方运行时也会调用这里:
ReadZipFile返回的是byte[],最终输入到下边运行:
这里lua文件名也就是chunkName(块名),最终由底层dll调用,此时运行实例便可看到main.lua的结果