Godot 4 错误 - 无效的集合索引“text”(基于:“Nil”),值类型为“int”

问题描述 投票:0回答:1
我是 Godot 新手,正在学习有关为 RPG 构建基本库存系统的教程。本教程逐步介绍了创建自定义资源,然后通过导出多个关键变量在节点中引用该资源的过程。

在我的代码中,我尝试分别将纹理和一些文本分配给纹理按钮和富文本标签节点。这是我的纹理按钮节点中的代码:

@tool extends TextureButton @onready var MyLabel = $RichTextLabel @export var MY_ITEM: Resource: set(newItem): MY_ITEM = newItem self.texture_normal = newItem.getTexture() print(newItem.getQuantity()) MyLabel.bbcode_text = newItem.getQuantity() func addQuantity(addedQuant: int): MY_ITEM.addQuantity(addedQuant)
这是我在自定义资源中的代码:

@tool extends Resource class_name RPG_Items @export var ITEM_NAME: String @export var QUANTITY: int @export var TEXTURE: Texture @export var HOVER_TEXT: String func addQuantity(addedQuant: int): QUANTITY += addedQuant func getTexture() -> Texture: return TEXTURE func getQuantity() -> int: return QUANTITY
当我运行此代码时,纹理已正确分配,但文本未正确分配,在标题中显示错误。

我尝试了多种方法来解决问题。排名不分先后,它们是:

    打印了我尝试分配给富文本标签的值(正如您从我的代码中看到的那样)。这有效,并且值被打印。
  • 将值转换为字符串。没有区别,错误只是从“...类型'int'的值”更改为“...类型'String'的值”。
  • 删除 bbcode 部分,取消选中富文本标签节点中的 bbcode 复选框,然后尝试“MyLabel.text”。没有什么区别。
  • 将富文本标签更改为普通标签并引用.text进行更新,但仍然出现相同的错误。
考虑到我对这一切还很陌生,我很可能忽略了一些非常小的事情,但我似乎无法弄清楚出了什么问题。欢迎任何建议,谢谢!

godot gdscript godot4
1个回答
0
投票
这与这个问题类似:

我收到错误“无效调用。基'Nil'中不存在函数'set'。”,除了Godot 3,并且您正在尝试设置属性而不是调用一个方法。


错误告诉您,您正在尝试在“on base: 'Nil'”上设置属性...因此您尝试设置的变量没有对对象的引用。

例如,如果您在以下行中收到错误...

MyLabel.bbcode_text = newItem.getQuantity()
这意味着

MyLabel

没有引用对象。这意味着要么

@onready var MyLabel = $RichTextLabel
未运行或失败(这将是另一个单独的错误)。

发生这种情况是因为 Godot 在初始化期间设置了

Node

 的变量,然后将 
Node
 添加到场景树中(因此在准备好之前)。因此,当您的属性设置器运行时,
@onready
变量尚未初始化。


我们将通过以下模式解决这个问题:

@tool extends TextureButton @onready var MyLabel = $RichTextLabel @export var MY_ITEM: Resource: set(newItem): if MY_ITEM == newItem: return MY_ITEM = newItem if is_node_ready(): _update() func _ready() -> void: _update() func _exit_tree() -> void: request_ready() func _update() -> void: if MY_ITEM != null: texture_normal = MY_ITEM.getTexture() MyLabel.bbcode_text = MY_ITEM.getQuantity()
因此,我们正在更新 

Node

_update
 的属性。

我们称之为:

  • Node
     准备就绪时(在 
    _ready
     中),使在 
    Node
     准备就绪之前对其属性发生的任何更改生效。
  • Node
     准备就绪并且属性发生更改时(在属性设置器中)。

备注:

  • 我们使用

    in_node_ready

     来了解 
    _ready
     是否已经运行。

  • request_ready

     退出场景树时,我们正在使用 
    Node
    ,因此 
    _ready
     下次 
    Node
     进入场景树时会再次运行(这支持从场景中删除 
    Node
     的用例树,更改其属性,然后再次添加)。

  • 我为未设置属性时的情况添加了空检查。您可能想为这种情况设置一些默认文本和纹理。

  • 在您的特定情况下,此模式仅对于

    MyLabel

     是必需的,当 
    Node
     准备好时,它就可用......所以您可以像往常一样在属性设置器中设置 
    texture_normal
     并且它会起作用。

  • 在更复杂的场景中,你可以有多个更新函数。可能是:

      所有属性都使用的单一更新功能
    • 每个属性都有一个更新函数(尽管很少需要)
    • 您通常会发现拥有多组相关属性,每组使用不同的更新函数是有意义的
    • 有时一个属性需要调用多个更新函数。
    是的,您可以从

    _ready

     称呼他们。


要明确的是,

_ready

@onready
Node
进入场景树时运行(无论是第一次,还是在我们调用
request_ready
之后)以及在
_ready
@onready
已经运行完之后孩子们。

© www.soinside.com 2019 - 2024. All rights reserved.