跳到主要内容

常见报错翻译和排查技巧

报错信息解析
attempt to index a nil value试图访问一个空值的属性或方法,一般来说是语句中的某个参数是空值,可以考虑用『输出调试日志』的方法来看看到底哪个值是nil
cannot wrap coroutine by main thread!!!主线程中不能包裹协程,可以参考TapTap案例:如何解决协程冲突的问题
badloop! free game session soon
more than 200,000,000 lua instructions in one tick, maybe bad loop
C stack overflow
逻辑中存在死循环或无限递归,如果该报错发生在服务端,会导致游戏局立刻结束
出现该问题的典型情况:
1.A函数调用B函数,B函数调用A函数
2.while语句条件有误,导致循环体持续执行
报错信息:projectName(项目名)/trigger_module_main.lua:XXX这里的XXX代表的是报错信息所在的lua文件的行数,也可以从这里去排查报错的原因
报错信息:projectName(项目名)/trigger_validator.lua: XXX这里的XXX代表的是报错信息所在的lua文件的行数,去trigger_validator.lua文件找到报错行数中报错的公式id,然后去trigger_validator.ts文件中搜索公式id找到报错的公式,就可以排查报错的原因了
触发器的服务端代码生成路径script/trigger_module_main_X.lua(X为任意数字),最好用vscode或者其他代码开发工具打开
触发器的客户端代码生成路径ui/script/trigger_module_main_X.lua(X为任意数字),最好用vscode或者其他代码开发工具打开

1.客户端/服务端遇到报错信息如何定位(找lua再找对应的触发)

提示:一般服务端的代码存储在项目根目录的script文件夹中,而客户端代码存储在项目根目录下ui/script文件夹中

服务端报错

根据错误提示我们可以知道这个问题是我们在trigger_module_main_1.lua文件的第122行出现了问题,且问题报错为:索引为空

因此我们打开项目文件的script文件寻找trigger_module_main_1.lua文件并打开

返回触发编辑器服务端中我们可以发现是在”游戏开始时“这个触发器中我们设置了一个新变量单位,但是并没有为它赋值便直接进行索引调用,进而引发报错

此时对它进行赋值后再次进行调试:发现问题已经解决

客户端报错

根据客户端报错信息我们需要打开我们本地的客户端代码,寻找对应的trigger_module_main_1.lua文件的74行代码

根据代码提示可以看出来,是我们的成就控件出错导致的客户端报错,此时需要打开客户端的触发查看成就所在的触发器进行查看

发现是由于成就面板的索引错误导致的索引值为空进而导致的报错。

重新更改成就控件的索引后再进行调试,发现正常

2.lua脚本空引用报错如何判空

Ⅰ:判断索引为空

在Lua脚本中,判断一个索引是否为空可以通过检查该索引的值是否为nil来实现。在Lua中,nil是一种特殊的类型,表示一个变量没有值。

①判断索引为空时:

-- 假设有一个表
local myTable = {}

-- 给表中赋值
myTable["someKey"] = "someValue"

-- 检查一个特定的索引是否为空
if myTable["yourKey"] == nil then
log.info("不存在索引:yourKey") -- 当索引不存在时输出:不存在索引:yourKey
else
log.info("索引不为空") -- 当索引存在时输出:索引不为空
end
-- 这段代码默认我们的表中只有somekey索引,因此当我们进行if myTable["yourKey"] == nil索引为空判断的时候会默认执行print("不存在索引:yourKey") ,如果将索引的key由 yourKey 更改为 someKey 则会执行第二条:print("索引不为空")

②判断函数索引为空

local myFunction = nil  -- 假设这是你要检查的函数

if type(myFunction) == "function" then
log.info("这是一个函数")
else
log.info("这不是一个函数")
end
-- 这里默认 函数为空 即local myFunction = nil ,会输出"这不是一个函数",若有函数则输出"这是一个函数"

Ⅱ:判断引用为空

在Lua中,引用通常是指一个变量指向了表(table)、函数、用户数据(userdata)。判断这样的引用是否为空,即判断它是否为nil,与前面提到的方法类似。

①判断表引用为空

local myTable = nil -- 假设没有分配表
if myTable == nil then
log.info("表引用为空")
else
log.info("表引用不为空")
end
-- 这里默认的是没有分配表,如果没有分配表的话会输出 "表引用为空" 如果分配表的话会输出"表引用不为空"

②判断函数引用为空

local myFunction = nil -- 假设没有分配函数
if myFunction == nil then
log.info("函数引用为空")
else
log.info("函数引用不为空")
end
-- 这里默认的是没有分配函数,如果没有分配函数的话会输出 "函数引用为空" 如果分配表的话会输出"函数引用不为空"

③判断单位是否为空

注意:对单位进行判空时需要判断单位是否有效

function unit_is_valid(unit)
return unit and unit:is_valid()
end