之前用的AB模拟加载机制,自定义写了一套加载流程,但是无法调试lua或者或者概率性能调试
因此写了一个新的加载流程框架完美解决了tolua加模拟调试不能debug的问题
原理:lua文件是通过路径来加载的,
- 设置好对应的加载路径(如:AddSearchPath)
- 设置好对应的加载方法(如:assetbundle)
- 设置好对应的加载方式(如:dofile(),dostring())
核心思路:
- 保证需要加载的文件全部加载完成
- 保证需要加载的文件入口准确
主要思路是:
原框架逻辑梳理:
- tolua的打包机制是 提前addbundle预加载包,和后续的ab包,整合在平台的如Android.manifest
- tolua的预加载是通过AddBundle()到指定查询路径
![73f93d66c503bdc5b39ea36d340cde85.png](https://i-blog.csdnimg.cn/blog_migrate/b4255758233f0f157ceebaf334442ba4.jpeg)
![391a8b7e80839b8de4437fdb37c8a308.png](https://i-blog.csdnimg.cn/blog_migrate/b7f1389122b0edd61956ee0a054344e0.jpeg)
- tolua框架加载方法如果是开启zip走zip方法LuaInterface.LuaFileUtilsReadZipFile(string fileName) 否则走正常加载 File.ReadAllBytes(string fullPath);
- 注:zip方法就是相对路径加载方法,通过searchPath来加载
- 否则走全路径加载方法(绝对路径LoadFIle)
![49ffb7aeea96d804c6ca4b1cb09c347c.png](https://i-blog.csdnimg.cn/blog_migrate/1720f7dcad745c2893b0b8ca6400514a.jpeg)
- 设置搜索路径 LuaFileUtils.Instance.AddSearchPath(path);
- Addbundle方法预加载走的是zip通道加载(注:addbundle之前必须保证bundle在StreamAsset文件夹中打包出来了,否则AddBundle失败)
那么我想法就是:之前为什么连不上,或者断断续续能断点
- 之前能加载,肯定是有socket连上了
- 但是因为部分tolua核心文件 require路径失败,导致逻辑无法执行,也就是无法挂上钩子也不报错
修正方案:
- 把tolua的lua文件全部改成自定义的加载方式(改成lua.txt文件,走我们自己写的ab渠道打包机制),这样全部tolua的自带文件和我们的代码就可以同时启动
- 自定义加载方法:把tolua的框架加载方法改成虚方法
- public virtual byte[] ReadZipFile(string fileName)
- 在自定义加载loader重写加载方法
- 我一开始的想法是tolua的lua文件用原逻辑加载,就是虚方法的zip(必须预先添加addbundle和searchpath)
![05361d565b80f6bd92bd85e87290d4b3.png](https://i-blog.csdnimg.cn/blog_migrate/b1bd28f8b18a8ce1895895eec051f259.jpeg)
- 原有的加载路径匹配上了就走默认加载,不然走自定义加载渠道
![b374d16a6fcd00e3a22cbdd15ea630c9.png](https://i-blog.csdnimg.cn/blog_migrate/b329b8342e2fac4d45207c9fc7a1bede.png)
- 但是发现这样搞,Android.manifest会对不上啊,两套打包机制是不合理的
- 那么我还是走了自己的打包流程,也就是需要手动把tolua里全部lua文件改成lua.txt后缀(有批量改名软件)
![aab57cbbf50973b13f0a51b8b7071505.png](https://i-blog.csdnimg.cn/blog_migrate/bd6d22df5e483987d171c0354a3fc303.png)
- 而且写了一套自动设置lua打包后缀的方法,以免出错,只设置.lua.txt文件,其他.lua文件呢就报错提示不匹配规则(暂不考虑变体,变体只需要改打包后缀.unity3d为其他)
- 打包后的路径为:一级路径:lua.unity3d
- 二级和多级路径为:lua/文件夹小写/文件夹小写.unity3d
- 因为lua/.unity3d是不允许的,在加载路径规则中.和/都是文件夹分隔符的意思
![d05b1b6167d118ee27b1c6c5a6ab7877.png](https://i-blog.csdnimg.cn/blog_migrate/f05a818061386425975b545440eb33b9.png)
- 但是tolua的文件太过于零零散散,我就整合在AssetBundle/Lua/ElHotLua文件夹内,看起来完美,但是根据打包规则,需要把tolua内部的全部require路径加多elhotlua(不区分大小写,打包和加载机制自动变小写),也就是比如
- Mathf = require "UnityEngine.Mathf"
- 需要改为Mathf = require "ELHotLua.UnityEngine.Mathf"
- 发现要改的地方很多,所以权衡下,把tolua完完整整拷贝到一级目录,就是AssetBundle/Lua文件夹内,就会造成真的很丑,先忍着,(因为框架更新再次替换tolua文件不这样搞会很麻烦,还需要重新挨个改引用(或许可以做匹配))
![18e9a95196b4c3faa9d01aa391f08eb2.png](https://i-blog.csdnimg.cn/blog_migrate/ce84ccd7733c3d21c1b045bda0ea99c4.png)
- 最后打包出来的文件如下:tolua框架的lua文件加载规则是lua_XX_XX.unity3d
![c0bd5f7677f57e112fb4ade932a62b3b.png](https://i-blog.csdnimg.cn/blog_migrate/714f362141e3418fd563c33fe58307b0.jpeg)
- 我们自己写的代码全部是lua/XX_XX.unity3d
![abe202478984a7971779bc36067244bd.png](https://i-blog.csdnimg.cn/blog_migrate/d68d0944e7432b360a568746534cfa4b.png)
- 那么这样就完美的把所有Tolua的文件和我们自己的文件一起打包了
- 打包完后,开始加载调试,发现socket连上了,逻辑正常了,但是就是不能断点
![162e22286e7966f7ee1451bc04c390d0.png](https://i-blog.csdnimg.cn/blog_migrate/f4aa22e51b05f48020d5f17419af968e.png)
- 为什么呢?我们来看下lua的调试文件
- 调试规则是在启动文件中链接LuaDebug.jit(注意debug文件必须与启动文件在同一个文件夹内,否则有坑无法链接上)
![782a8c2303601ffb3393c9f274adc3c3.png](https://i-blog.csdnimg.cn/blog_migrate/1d042de80da1be0a0c1b945cbcbd0424.png)
- 启动入口方法是StartDebug
![29b2fe551980bf625afb683ad2b3e420.png](https://i-blog.csdnimg.cn/blog_migrate/63a52e47e5fa1f47188d4dad6c9a7b96.jpeg)
- socket的ip和端口的启动方法
![878a40a57e688da695c9d9c3ab98e292.png](https://i-blog.csdnimg.cn/blog_migrate/15f3bad6bf73b50bbdd6daff0fe2e622.jpeg)
- 钩子程序通过xpcall(function,function)调用
- debugger_loop()方法检测
- _resume()协程挂起调试
-
- 经过各种打印得到socket连接,但是钩子挂起始终不生效
- 那么,到底是阻塞失败了
- 还是没有断点呢(断点信息已经打上了啊)
- 经过各种打印得到socket连接,但是钩子挂起始终不生效
-
- 经过询问LuaIDE的作者K大神得知,自定义加载渠道,如果不是DoFile的话,而是DoString()是需要附加上chunkName的(疏忽没检查这个了),而且luadebugjit和启动类必须在相同路径
![ea7c520e60546ac38dfd7b3e122a1af7.png](https://i-blog.csdnimg.cn/blog_migrate/386ce9e60aeb43de993420a9ba3da6b8.png)
- 经过最终测试,问题解决了,贴图证明
![8941d384aa485c752959f084daf2a226.png](https://i-blog.csdnimg.cn/blog_migrate/99d8a32f190eb267f5aa8c44149c149d.jpeg)
- 总结如下:自定义AB热更加载框架,必须完完整整(重要的事情说三次)把tolua的文件加载进来
- 请注意是DoFile(string fileName)还是DoString(string chunk, string chunkName = "LuaState.cs")
- 启动文件luadebugjit.lua.txt必须和启动类main.lua.txt在相同路径
- 注意socket端口是否被其他程序占用
- tolua文件必须和自己写的文件一起打包(无论是AB打包还是模拟加载)
- 剩下的就是自定义打包流程和加载流程了,预知后事如何,请关注下篇(如何实现AssetBundlea模拟加载)