For loop 由于不相关的表索引分配,Lua'尝试调用..in'附近的数值时出错--为什么?

For loop 由于不相关的表索引分配,Lua'尝试调用..in'附近的数值时出错--为什么?,for-loop,lua,iterator,tabletop-simulator,For Loop,Lua,Iterator,Tabletop Simulator,我正在桌面模拟器中编写一些Lua脚本,看到错误试图调用接近..的数值,这让我完全困惑。下面是导致错误的for循环的代码段: function resetTurnOrder() local map = getObjectFromGUID(GUIDs.Map) local shift, center, points = map.getPosition(), map.getTable('MapData').center, map.getSnapPoints() local i,

我正在桌面模拟器中编写一些Lua脚本,看到错误试图调用接近..的数值,这让我完全困惑。下面是导致错误的for循环的代码段:

function resetTurnOrder()
    local map = getObjectFromGUID(GUIDs.Map)
    local shift, center, points = map.getPosition(), map.getTable('MapData').center, map.getSnapPoints()
    local i, p = 0
    for nation, guids in pairs(GUIDs.Nations) do
        print('Resetting turn order for ' .. nation)
        if checkScenario(nation) then
            i = i + 1
            p = map.positionToLocal(shift - points[i].position)
            p[1] = p[1] * 0.75 + center[1] * 0.25
            p[3] = p[3] * 0.75 + center[3] * 0.25
            getObjectFromGUID(guids.turn_token).setPositionSmooth(map.positionToWorld(p), false, false)
            getObjectFromGUID(guids.turn_token).setRotationSmooth({0, points[i].rotation[2], 0}, false, false)
            print('Done resetting turn order for ' .. nation)
        else
            print(nation .. ' not in this scenario')
        end
    end
end
好的,首先我要说,通过注释掉直接分配给p[1]和p[3]的两行,错误消失了,当我用等价的语句替换这些行时

p = {p[1] * 0.75 + center[1] * 0.25, p[2], p[3] * 0.75 + center[3] * 0.25}
然后一切都很顺利。然而,我完全目瞪口呆,不知道为什么这会修复错误。我在大约六个地方使用了这个精确的for循环定义来迭代存储在全局guid中的播放器及其组件,它在其他任何地方都能完美地工作

为了添加更多细节,即使使用旧代码,循环的第一次迭代也能完美地工作。第一个回合标记被移动到其正确位置,两条消息都被打印,但错误会阻止进一步的迭代。当递增循环迭代器时,错误显然会发生,但我不明白直接赋值给p[1]和p[3]会如何影响这一点,但赋值给p是可以的。还有一个细节:在for循环中声明p而不是事先在外部声明p没有帮助

编辑以添加更多详细信息

经过更多的测试后,@luther可能是正确的,positionToLocal返回的值的元表发生了一些奇怪的事情。这个函数返回的值是Tabletop Simulator定义的向量,我认为它是Unity的Vector3类型的扩展。一个重要的细节是,这种类型允许您互换地引用索引x、y、z和1,2,3

因此,我用p.x和p.z替换了p[1]和p[3]赋值,从而修复了错误。这似乎意味着positionToLocal返回的向量没有明确定义索引1、2、3,而是使用元方法将这些索引链接到x、y、z。而且,不知何故,这个元方法正在与循环迭代器发生冲突。。。但老实说,这仍然让我感到困惑

Nations是传递给pairs函数的表,该函数用于生成迭代器,它基本上是一个常量,我从不在任何函数中添加或更新它,因为它包含静态GUID。它当然与p没有关系

进一步详情

这显然可能与桌面模拟器的矢量实现有关:

上面的示例只是使用一个简单的数字for循环来更新向量值的索引1、2、3,而使用i索引向量的赋值语句最终将i的值更改为分配的相同值


我仍然无法理解这在语言中是如何实现的,尽管…

好的,我确定这是Moonsharp中的一个bug,它是桌面模拟器使用的Lua解释器:


该错误于2016年3月修复,但TTS可能尚未更新Moonsharp。

可能positionToLocal返回了某个带有元表的内容,该元表的新索引正在做一些奇怪的事情。错误消息指向哪一行?@luther,我想你已经找到了。positionToLocal返回一个Vector3,它是一个统一类,肯定有一个元表。