Lua 保持全局变量值不变

我使用 Lua 编写游戏引擎逻辑。我的主游戏循环不是在 Lua 中完成的。场景层次结构中只有特定的节点附有 Lua 脚本。这些脚本每帧执行一次。我面临的问题是我需要在帧之间保留全局变量的值。

我的临时解决方案如下:

finish = useBool("finish", false)
timer = useInt("timer", 0)
showTimer = useBool("showTimer", true)
startTimer = useInt("startTimer", 0)
play0 = useBool("play0", false)
play1 = useBool("play1", false)
play2 = useBool("play2", false)
play3 = useBool("play3", false)
delta = useInt("delta", 0)
gameOverTime = useInt("gameOverTime", 5000)
finishTime = useInt("finishTime", 5000)
checkPoint = useInt("checkPoint", 255)

<...> 游戏逻辑 <...>

setInt("message", message);
setInt("checkPoint", checkPoint)
setInt("finishTime", finishTime)
setInt("gameOverTime", gameOverTime)
setInt("timer", timer)
setBool("play3", play3)
setBool("play2", play2)
setBool("play1", play1)
setBool("play0", play0)
setInt("startTimer", startTimer)
setBool("showTimer", showTimer)
setInt("timer", timer)
setBool("finish", finish);

我调用特殊的方法,在 Lua 中从 C++ 的哈希映射中检索全局变量,并在脚本末尾再次设置它们。

是否有一种隐式的方式来实现这个?

将 Lua 用作主游戏循环是不是一个不好的设计?

点赞
用户1632532
用户1632532

好的,虽然你的方法在技术上并没有问题,但是如果你的全局变量变得很多(一般情况下应该避免这种情况),你可能会开始注意到一些性能问题。

有了这个说法,还有改进的空间。例如:

在脚本开头,检查你的全局变量是否为nil。如果是,那么你可以初始化它,否则,这可能不是第一次运行脚本,所以不要修改它。但这意味着有很多麻烦的if-else语句,很容易忘记。我们可以做得更好!

我建议看一下《Lua 编程》书中的第14章:环境。以下是简介的引述:

Lua 将所有全局变量存放在一个名为环境的普通表中。... 其他(实际上是主要的)优点是,我们可以像处理任何其他表一样操纵此表。为了便于这样的操作,Lua 将环境本身存储在全局变量 _G 中。(是的,_G._G 等于 _G。)

由于_G是一个表,所以它也有元表,因此你可以定义__index__newindex元方法来处理对全局变量的访问和创建。你可以在第14.2节中找到这方面的例子。去读整个章节,它并不长。(如果你不熟悉元方法和元表,还要阅读第13章 - 这是 Lua 在灵活性方面真正闪耀的地方。)

现在我们已经涵盖了普通和正常的方法,让我们看看过度的范围。以 Unity 对脚本的方法为例。Unity 的 javascript 通常定义变量、函数和类型。在方法或类型范围之外定义的任何变量在帧之间保留,因为脚本本身并不会在每帧都执行。相反,他们让脚本定义函数并在适当的时间调用函数。所以如果你想让某些东西在每一帧都执行 - 把它放在Update函数中。每个脚本都可以定义它自己的Update函数,因为它有它自己的作用域。因此,每一帧脚本引擎都会遍历所有对象,检查脚本的作用域是否有Update方法并调用它。

回到 Lua - 这样的解决方案涉及为每个对象/脚本/节点创建单独的环境。然后,你的主循环将遍历所有节点并在它们的环境中运行一个函数,而不是每个帧都执行附加到你的节点的脚本。你还可以切换环境,这样你可以在执行它之前将全局环境设置为你的节点的环境,然后在完成时切换回来。这允许你的脚本按照自己的想法使用全局变量,使它们在帧之间持久化,并且可以排除名称冲突或全局命名空间污染的可能性。此外,你可以使用元方法将节点环境嵌套在实际全局环境或具有辅助方法的 API 环境中(基本上,如果__index找不到某些东西,它会在“父级”中查找)。

2012-11-22 10:24:16