【问题标题】:Godot: Getting a node results in Nil ValueGodot:获取节点导致 Nil 值
【发布时间】:2022-02-09 14:12:11
【问题描述】:

我正在尝试进入 Godot。在我的项目中,我想在附加到 Dash 节点的 Dash 脚本中访问一个名为 Duration Timer 的计时器。

Screenshot - Godot get Duration Timer

我已经尝试了 3 种方法来访问屏幕截图第 4,5 和 6 行中看到的节点。

onready var duration_timer = $DurationTimer
#onready var duration_timer = get_node("DurationTimer")
#onready var duration_timer = get_node("Movement/Dash/DurationTimer")

所有 3 行都会导致突出显示的错误消息

“无效的设置索引'wait_time'(基于: 'Nil'),值为 'int' 类型。

错误出现在第 14 行,因为尝试将 wait_time 设置为 Timer 元素。

duration_timer.wait_time = 1

有人知道为什么我无法获取 Timer 元素吗?

【问题讨论】:

  • 我只能猜测你正在运行代码 duration_timer.wait_time = 1 一次 duration_timer 未设置。可能还没有设置。那么,您在哪里调用该代码?另外,如果你做$DurationTimer.wait_time = 1,它会起作用吗? 顺便说一句get_node("Movement/Dash/DurationTimer") 是错误的。 编辑:代码是在移动还是在破折号?在图像中,我看到get_node("Dash") 表明代码正在移动,因为它应该是get_node("Dash/DurationTimer")
  • 嘿Teraot,感谢您的评论。您在屏幕截图中看到的代码附加到 Dash 节点。 $DurationTimer.wait_time = 1 导致相同的错误:无效的设置索引“wait_time”(基于:“null instance”),值为“int”类型。是的,我已经玩了一段时间了,用不同的符号来获取计时器,但我仍然无法让它工作。从 Player.gd 调用 start_dash 函数

标签: timer get game-development godot onready


【解决方案1】:

我不知道是什么导致了问题。

我不认为get_node("DurationTimer")$DurationTimer 是错误的。但如果这是问题所在,我们可以使用NodePath 来解决它:

export var duration_timer_path:NodePath
onready var duration_timer = get_node(duration_timer_path)

然后从检查面板设置NodePath


如果路径没有错。可能是代码在_ready 之前运行。或者某些东西(我不知道是什么)删除了计时器或将其设置为空。 当游戏从编辑器运行时,您可以添加断点并检查场景树面板的远程选项卡,以查看计时器是否存在。

如果我们没有计时器,我们可以通过制作一个新计时器来回避这个问题。例如:

if not is_instance_valid(duration_timer):
    duration_timer = Timer.new()
    duration_timer.name = "DurationTimer"
    add_child(duration_timer)

# use duration_timer here

但是,如果计时器存在但我们未能获得它,我们将在场景树中拥有两个计时器。 如果这导致两个计时器,您还可以检查场景树面板的远程选项卡。

所以,让我们再次尝试获取节点,以防我们第一次失败。让我们把它放在一个方法中。像这样的:

func get_duration_timer() -> Timer:
    if is_instance_valid(duration_timer):
        return duration_timer

    duration_timer = get_node("DurationTimer") # or use a NodePath
    if is_instance_valid(duration_timer):
        return duration_timer

    duration_timer = Timer.new()
    duration_timer.name = "DurationTimer"
    add_child(duration_timer)
    return duration_timer

事实上,如果我们在这种情况下,那么onready 对我们没有帮助。所以我们可以在没有onready 和初始化的情况下定义duration_timer。并且始终使用获取计时器的方法。

如果我们要一直使用该方法,为什么不让该方法添加计时器而不是将其添加到场景树中呢?然后我们可以删除尝试获取它的步骤:

func get_duration_timer() -> Timer:
    if is_instance_valid(duration_timer):
        return duration_timer

    duration_timer = Timer.new()
    duration_timer.name = "DurationTimer"
    add_child(duration_timer)
    return duration_timer

我们这里有一个惰性初始化模式:计时器是在我们第一次需要它时创建的,按需而不是之前。

【讨论】:

  • 嘿 Theraot,再次感谢您。通过代码添加计时器就可以了。我现在要使用这种方法,但我仍然不明白为什么我无法获得我在场景树中手动添加的 DurationTimer 元素。 export var duration_timer_path:NodePath 并通过 ui 分配节点不起作用。
猜你喜欢
  • 2021-08-22
  • 2021-12-26
  • 1970-01-01
  • 2015-04-20
  • 1970-01-01
  • 2013-08-10
  • 2013-03-19
  • 2011-08-01
  • 1970-01-01
相关资源
最近更新 更多