从 Godot 中的另一个脚本访问 var

Access var form another script in Godot

我搜索了有关主题的信息,但我做不对,谁能帮我吗?

节点 World 包含 2 个子节点 - Pe2nodeHUDPe2node (Node2D) 节点已附加 pe2.gd 脚本并且它有变量 - shiftHUD 节点 (CanvasLayer) 已附加 HUD.gd 脚本,我想显示变量 shift 来自Pe2node。我尝试了一些变体,但它根本不起作用。我已经准备好尝试自动加载,但可能有简单的方法让它工作。 HUD.gd:

extends CanvasLayer

var fps=0
var shift_hud=0

func _process(delta):
    fps = Engine.get_frames_per_second()  
    $var_fps.text=str(fps)
    #shift_hud=get_node("Pe2node").get_variable("shift")
    #shift_hud=get_node("Pe2node").shift
    #shift_hud=get_node("World/Pe2node").shift
    #shift_hud=$World/Pe2node.shift
    $var_shift.text=str(shift_hud)

Node World contain 2 children - Pe2node and HUD

也就是说Pe2nodeHUD是兄妹对吧?

让我们回顾一下您的尝试:

  1. get_node("Pe2node")
    

    这是在寻找当前节点的 "Pe2node" 个子节点,而不是兄弟节点。

  2. get_node("World/Pe2node")
    

    现在您正在寻找当前节点的 "World" 个子节点的 "Pe2node" 个子节点。

  3. $World/Pe2node
    

    同上

您可以像这样更上一层楼:

get_node("../Pe2node")

或者像这样:

$"../Pe2node"

或者你可以有一个绝对路径,我不会举个例子,但是如果你 print 在你想要的 Node 上调用 get_path 的结果,它会显示绝对路径(以 "/root/" 开头)。


我经常不建议按照我上面描述的方式进行操作的原因是因为它取决于这些节点的相对位置,您可能不会一起移动,从而破坏代码。

一个更好的方法 - 无需自动加载解决方案 - 是导出 NodePath:

export var node_path:NodePath

您可以在检查器面板中将其设置为您想要的节点。然后我们用它来获取节点:

get_node(node_path)

只要您连接的东西从一开始就在场景树中(您不是试图动态实例化某些东西),这将起作用。只要是这种情况,并且您只从 Godot 界面操作场景,Godot 就可以保持 NodePath 更新。


根据自动加载解决方案,我建议将信号放在那里。您可以使用这样的信号自动加载:

extends Node

signal shift_changed(value)

这就是自动加载的全部代码。

您可以创建该脚本,然后将其添加为项目设置中的自动加载,并使用一些名称。我将使用名称 SingalBus.

然后从任何地方发出信号:

SingalBus.emit_signal("shift_changed", value)

并从任何地方连接到它:

SingalBus.connect("shift_changed", self, "_on_shift_changed")

其中采用了类似这样的方法:

func _on_shift_changed(value) -> void:
    pass

这意味着您根本不再需要任何类型的节点路径,因此没有可能中断的路径。另外,您可以仅在值更改时更新 UI,而不是一直检查它。另一边可能没有东西,所以这也适用于动态实例化的东西。


公平地说,您可以将变量而不是信号放在自动加载上。这也有效。在某些情况下,在此处放置对 Node 的引用很有用。

将变量放在那里的好处是,它还为您提供了一个单独的位置来放置它们,这对于 save/load 功能也可能有用,并且在从一个开始时也可以将它们保留在周围另一个场景。