我正在尝试制作一个游戏,但我需要像全局变量之类的东西才能使其工作。 GDscript 中有没有一种方法可以让您使用脚本创建一个在所有节点上工作的变量。我需要一个按钮,让你购买一把枪,它将一个变量设置为 true,并且该变量为 true,你就可以装备枪。
这个问题并不真正适合本节,它说:你尝试了什么以及你期望什么?所以我就跳过它。
从 Godot 4.1 开始,你可以使用静态变量:
static var my_variable := true
脚本的所有实例都将共享这些变量。
您还可以使用
Globals
来实现相当于 class_name
自动加载,如下所示:
class_name Globals
static var has_gun := false
您不需要注册为自动加载。您只需要在项目中的某个位置放置此脚本即可。
Godot 还有静态方法 (
static func
),您可以从任何地方调用它们。
请注意,这种方法会造成不方便的信号总线,因为目前没有静态信号(提案)。但有一些解决方法,请参阅:如何在 GDScript 中编写静态事件发射器?.
GDscript 中有没有一种方法可以让你使用脚本创建一个在所有节点上工作的变量。
您可以使用自动加载。
转到“项目”菜单,“项目设置”选项,在“自动加载”选项卡中...您可以在其中设置脚本并为其命名。它将适用于场景树中的每个节点。
例如,您可以有一个如下所示的“globals.gd”脚本:
extends Node
var has_gun := false
然后将其设置为自动加载,名称为“Globals”。因此,您可以在任何其他脚本中使用它。例如:
extends Node
func _ready() -> void:
print(Globals.has_gun)
是的,即使您更改当前场景,自动加载也会保留在那里。
您可能还对信号总线(事件总线)模式感兴趣,该模式涉及在自动加载中定义信号,以便其他脚本发出它们或连接到它们。
从技术上讲,自动加载并不是真正的全局。正如我所说,自动加载将可用于场景树中的节点。
这也意味着自动加载对于不是
Node
的脚本(例如 Resource
)或不在场景树中的脚本不可用。
除非您使用一种巧妙的解决方法来获取对自动加载的引用,我不会讨论这一点。
相反,我会给你一个替代方案:基于资源的沟通。
这次您创建一个“global_resource.gd”,如下所示:
class_name GlobalResource
extends Resource
var has_gun := false
然后您可以使用“文件系统”面板上的上下文菜单来创建新资源。当 Godot 询问您类型时,您选择
GlobalResource
,并为其命名,例如“globals.tres”。
然后你可以像这样使用它:
extends Node
const Globals := preload("res://globals.tres")
func _ready() -> void:
print(Globals.has_gun)
无论您在哪里
preload
相同的资源文件(“globals.tres”),您都会获得相同的Resource
实例。无论是在同一个场景中,还是更改了当前场景,都没有关系。
是的,这不依赖于场景树。是的,您也可以在其中放置信号。
为了完整起见,我还要提到还有另一种巧妙的解决方法,其中涉及在具有类名的脚本中将
Dictionary
或 Array
定义为 const
。因为在 Godot 3 中,const
并不意味着不可变(在 Godot 4 上不要指望这一点)。这就是目前一些人解决静态变量缺乏问题的方法。不过,我相信你不会觉得有必要。
附录:您可以在项目 - >项目设置中添加自定义属性...并且您可以在那里给出其默认值(甚至每个目标平台都有不同的默认值)。在运行时,您可以使用
ProjectSettings.get_setting
读取它们或使用 ProjectSettings.set_setting
写入它们。