微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Godot - 缺少节点

如何解决Godot - 缺少节点

这很难用打字来解释...

我有一个 GameController 场景 (Node2D),其中包含 3 个实例化场景:

  • 鼠标 (scenes/Mouse.tscn) - 这只是将鼠标光标交换为自定义图形
  • HeaderBar (scenes/HeaderBar.tscn) - 这是刚好位于顶部的分数/标签
  • Messages (scenes/Messages.tscn) - 这是向用户显示文本的“弹出”消息框

在主场景 (Level1.tscn) 中,我实例化了 GameController 场景,它“工作”得很好。标题栏和分数/标签在那里,自定义鼠标光标在那里,消息框也在那里(但我认隐藏它,但如果我在遥控器中切换它的可见性,它会显示出来)。

这就是我的困惑所在......

如果我尝试在 GameController 脚本中操作 GameController 场景中的任何节点(鼠标、标题、消息),它们将返回 null 并抛出错误。例如;如果我尝试更新 $HeaderBar/Control/score 中的分数,我会得到以下结果:

Invalid set index 'text' (on base: 'null instance') with value of type 'String'.

代码完成将在我键入节点名称自动填充节点名称(因此它可以识别组中的节点名称),但任何在脚本中引用/使用它们的尝试都会引发与上述类似的错误

我对 Godot 很陌生,所以我确定这只是我对这种类型的工作方式的一些误解,但我很难过!非常感谢任何见解!

更新

我会尽量简化我的解释(我做了一些更改)。好的,这是对象脚本:

extends StaticBody2D

onready var main = load("res://scenes/MainGame.gd").new()

func _ready():
    pass

# mouse [left] clicked on object
func _on_trigger_input_event(viewport,event,shape_idx):
    if Input.is_action_just_pressed("left-click"):
        main.display_message("you [left] clicked on the object!")

对 main.display_message() 的调用有效。它确实调用函数,但这是 MainGame.gd 中的该函数

extends Node2D

onready var Box = $Message/Control
onready var label = $Message/Control/Label


func _ready():
    # hide the mouse cursor (will use custom cursor)
    Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
    
func display_message(msg):
    label.text = msg
    Box.visible = true

它出错是因为标签(和框)为空。如果我从 _ready 函数(在 MainGame.gd 中)调用 display_message 它会正常工作。从外部(在 Object.gd 中)调用它,节点由于某种原因为空。

解决方法

这按预期实例化了场景:

onready var main = load("res://scenes/MainGame.gd").new()

但是,当实例化场景添加到场景树中时,此代码将运行:

onready var box = $Message/Control
onready var label = $Message/Control/Label


func _ready():
    # hide the mouse cursor (will use custom cursor)
    Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)

是的,当它添加到场景树时,onready 变量和 _ready 都会运行。

什么时候将 main 添加到场景树中?我不知道在哪里。

然后当你这样做时:

main.display_message("you [left] clicked on the object!")

boxlabel 都将仍然为 null(这是默认值)。

因此,将其添加到场景树中,例如:

func _ready():
    add_child(main)

除了这也不起作用,是吗?再看代码:

onready var main = load("res://scenes/MainGame.gd").new()

您正在实例化一个脚本。一个脚本。不是一个场景。它不会有它的子节点等等。你想实例化一个场景,例如:

onready var main = load("res://scenes/MainGame.tscn").instance()

但是,我觉得您在 StaticBody2D 中这样做很奇怪。我认为 MainGame 属于 StaticBody2D 是没有意义的。

我怀疑,您正在多个地方实例化 MainGame,期望它是同一个实例。但它不是同一个实例,它是一个新实例

这里是我建议您将 MainGame 设为自动加载的地方,这样您就可以从任何地方访问单个实例。然而,也许这也不对。也许您应该使用信号总线。请参阅Why does this variable keep returning to its original value?,其中有类似的问题(他们试图打开门,您试图显示消息,但仍然如此)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。