我正在 Tabletop Simulator 中编写一些 Lua 脚本,并看到让attempt to call a number value near for..in
我完全困惑的错误。这是导致错误的带有 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
好的,首先我会说,通过注释掉直接分配给and的两行,错误消失了,当我用等效语句替换这些行时p[1]
p[3]
p = {p[1] * 0.75 + center[1] * 0.25, p[2], p[3] * 0.75 + center[3] * 0.25}
然后一切正常。但是,我完全不知道为什么这会修复错误。我在大约六个地方使用这个精确的 for 循环定义来迭代播放器及其组件(存储在 global 中GUIDs
),并且它在其他任何地方都可以完美地工作。
添加更多细节,即使使用旧代码,循环的第一次迭代也能完美运行。第一个回合标记被移动到它的正确位置,两个消息都被打印,但错误阻止了进一步的迭代。递增循环迭代器时显然会发生错误,但我无法理解如何直接分配给p[1]
并且p[3]
可能会干扰这一点,但分配给p
很好。更多细节:p
预先在 for 循环内部而不是外部声明没有帮助。
(编辑添加更多细节)
经过更多测试后,看起来@luther 可能是正确的,因为positionToLocal
. 此函数返回的值是Vector
由 Tabletop Simulator 定义的,我相信它是 UnityVector3
类型的扩展。一个重要的细节是,这种类型允许您可以互换x,y,z
地引用索引。1,2,3
所以,我用 and 替换了p[1]
andp[3]
赋值,p.x
它p.z
修复了错误。这似乎意味着Vector
返回的 bypositionToLocal
没有1,2,3
明确定义索引,而是使用元方法将这些索引链接到x,y,z
. 而且,不知何故,那个元方法正在搞乱循环迭代器......但老实说,这仍然让我大吃一惊。
GUIDs.Nations
是传递给pairs()
用于生成迭代器的函数的表,它基本上是一个常量——我从不在任何函数中添加或更新它,因为它包含静态 GUID。它当然与p
.
更多详细信息
这似乎肯定与桌面模拟器的 Vector 实现有关:https ://forums.tabletopsimulator.com/showthread.php?8344-For-loop
上面的示例仅使用一个简单的数字 for 循环来更新1,2,3
Vector 值的索引,并且用于索引 Vector 的赋值语句i
最终将 value 更改i
为分配的相同值。
我仍然无法理解这在语言中是如何实现的......