原生的lua代码调试支持的工具很多, 这里主要说的是能Attach到Unity进程交互调试的工具。 大多游戏都在使用lua脚本来热更新游戏逻辑,下面介绍两个工具如何调试lua,

  • jetbrains旗下软件(IntelliJ IDEA、 Pycharm、 Rider等)
  • vscode(LuaPanda)

两款ide都是跨平台的, 在windows和macos上都有很好的支持, 而且都支持以下lua的特性:

  • 自动补全(auto completion)
  • 代码片段(snippet completion)
  • 定义跳转(definition)
  • 生成注释(comment generation)
  • 类型推断(limited type inference)
  • 代码格式化(formatting): vscode依赖 lua-fmt
  • 代码诊断(linting):vscode依赖 luacheck
  • 调试器(debugger)

Jet brains 工具链

下载安装IntelliJ IDEA 或者pycharm, 这两款软件都是Jet Brains旗下的软件。 现在更多的人使用它们来开发python或者java, 我们这里主要使用的是其一款插件,叫做EmmyLua

以Pycharm为例:

安装好之后,选择File->Settings, 再打开的设置窗口选中Plugins来安装插件, 搜到EmmyLua, 点击Install按钮,进行安装:

选择Unity工程lua脚本所在的文件夹打开(注意lua require时搜索路径,所以这里一定对应起来)。

增加识别文件扩展名,将.lua 和.txt统统识别为lua脚本,(*.lua.txt能识别为lua,但影响debug, 可能是emmylua的一个bug)

在上图选项Ignore files and folders 可以设置忽略在侧边栏显示的文件匹配符。很多非代码相关的东西都可以通过此方式屏蔽掉。

菜单栏选中Run->Attach to Process, 在本机所有的进程中选择Unity进程即可调试了。

运行效果如下, 既可以看到调用堆栈, 又可以查看过程变量,非常的方便。

如果你不习惯pycharm自带的快捷键, 你还可以在setting的Keymap中改成vs的快捷键。除了vs的快捷键, pycharm还提供了很多其他编辑器的快捷键, 比如说Sublime, Eclipse等。

如果你之前是一名python开发者, 第一次打开一个lua的工程的时候, pycharm会加载很多python本地安装的packages, 如果这影响了编辑器的性能,你可以在Settings里面清掉Project interpreter:

如果你是一位原生的lua开发者, 而非使用引擎调试lua, 你需要配置编译好的lua.exe的文件位置和lua的search path, 配置好之后也能很方便的调试。

Lua Check

关于lua的静态检查工具很多,这里着重介绍两种方法:

1、luac.exe

也就是lua的编译器,安装完lua的编译器之后,将自己的代码进行编译这是最好不过的静态检查,当然编译器由于参数的设置,对很多告警并不敏感。所以推荐第二种方法。

2、luacheck

这是google推出的一款针对lua静态检查的开源工具,其安装简单,操作容易,检查严格,参数可控,很适合项目的lua开发。

EmmyLua 支持luacheck语法检测, 首先需要去github下载对应平台的luacheck, 比如说windows平台是.exe, 如果不存在对应的平台release版本, 请下载c++源码编译对应平台的版本。下载完成之后, 如下图配置luacheck路径:

配置好之后, 在lua的代码区右键选择luacheck, 就可以在LuaCheck窗口看到一些语法警告信息:

VSCode

这里推荐一款vscode的plugin, 腾讯开发的插件叫LuaPanda, 因为LuaPanda是基于luasocket的, 所以你必须确保你的lua环境已经安装了luasocket, 又鉴于此特性,所以这款插件还可以远程调试(需在同一局域网内, 并且可以pin通), 比如说手机连着编辑器调试。关于更多的联机调试, 查看文档

LuaPanda的vscode adapter是使用typescript(javascript的超集) 语言编写的, 大约1000行,核心代码: luaDebug.ts

文件配置

文件:LuaPanda.lua

下载位置:github 的 Debugger 目录下

把以上两个文件放在lua代码可以引用到的位置,并在用户代码中引用:

require(“LuaPanda”).start(“127.0.0.1”,8818);
*8818是默认端口号,如果需要修改,请同时修改launch.json的端口设置。

调试配置

切换到VSCode的调试选项卡,点击齿轮,在弹出框中选择 LuaPanda (若无此选项说明以前用别的插件调试过lua , 要把先前用过的调试插件禁用)。会自动生成launch.json文件。

launch.json 配置项中要修改的主要是luaFileExtension, 改成lua文件使用的后缀就行。(比如xlua改为lua.txt, slua是txt)。各配置项鼠标悬停会有提示,可根据需要更改。

先运行VSCode端,再运行Lua代码: 点击调试选项卡左上角的绿色箭头,再运行unity/ue4工程。如果有stopOnEntry或是执行到断点处,就会自动停住。

LuaPanda 在PC上调试会默认使用 c hook,它是用c重写了debugger的核心hook部分,从而提高调试器的执行效率。 c hook会默认启用,无需单独接入。

验证方式:停在断点处后,在调试控制台输入LuaPanda.getInfo(), 返回信息的BaseInfo会给出提示,如果c库已加载,还会给出版本号。

LuaPanda调试器功能依赖LuaSocket, 可运行于slua,slua-unreal ,xlua 等已集成 LuaSocket 的 lua 环境,也可以在console中调试。lua 版本支持 5.1- 5.3。

其他依赖项目(插件中已包含,无需用户手动安装):

luaparse
luacheck
lua-fmt
path-reader

更多关于LuaPanda的介绍, 参考这里

原生Lua的调试

针对原生的lua调试, 建议使用本地安装luarocks, 以mac为例, 打开终端

brew install luarocks

windows 安装使用luarocks, 比较麻烦, 具体可以参考这篇文章

这里调试用到了luasocket了, 所以本地需要安装luasocket. 如果你安装有 Lua 模块的安装和部署工具 – LuaRocks,那么一条指令就能安装部署好 LuaSocket:

luarocks install luasocket

验证luasocket是否安装成功, 写一个lua脚本

require("socket")

运行如果没有报错, 就证明安装成功了。 如果报错如下:

LuaScriptException: error loading module 'socket.core' from file '/usr/local/lib/lua/5.1/socket/core.so':
    dlopen(/usr/local/lib/lua/5.1/socket/core.so, 2): no suitable image found.  Did find:
    /usr/local/lib/lua/5.1/socket/core.so: mach-o, but wrong architecture

则是因为在 64bit Mac OSX 下使用 luarocks 编译安装的 luasocket 默认是 x86_64 架构的,所以出现不兼容情况。

需要修改 luarocks 的编译和链接参数,增加 i386 构架的支持:

vim /usr/local/share/lua/5.3/luarocks/core/cfg.lua

找到 if detected.unix then 后面的 defaults.variables.CFLAGS 在参数中追加 -arch i386 -arch x86_64

if detected.unix then
    ...
    defaults.variables.CFLAGS = "-O2 -arch i386 -arch x86_64"
    ...

同上,找到 if detected.macosx then 后面的 defaults.variables.LD 在参数中追加 -arch i386 -arch x86_64

if detected.macosx then
    ...
    defaults.variables.LD = "export MACOSX_DEPLOYMENT_TARGET=10."..version.."; gcc -arch i386 -arch x86_64"
    ...

保存 cfg.lua 后重新安装 luasocket 即可:

luarocks install luasocket

在JetBrains的产品,比如Rider中设置lua的安装路径和搜索路径,以及执行入口lua文件:

设置之后,点击运行按钮,能得到和Attach Unity进程一样的体验, 既能看运行内存的一些变量,还能添加一些监视, 比如下图去查看某些table的原表。

写在最后

由于作者经常使用pycharm写python脚本, 已经很熟悉Jetbrains的那一套环境了,所以我更倾向于使用第一种方式来调试lua。 然而vscode显然更轻量级一些, 读者喜欢使用哪一款,萝卜青菜 各有所爱吧。