Bug

GbWqqU.png
这是原本的代码结构图。
下面代码想实现的意图是当玩家生命值修改时,会发信号给update_healthbar(value)这个函数。实现修改HUD显示层的生命条的功能。

extends CanvasLayer

var bar_red = preload("res://assets/UI/barHorizontal_red_mid 200.png")

var bar_green = preload("res://assets/UI/barHorizontal_green_mid 200.png")


var bar_yallow = preload("res://assets/UI/barHorizontal_yellow_mid 200.png")


var bar_texture 

onready var health_bar = get_node("Margin/HBoxContainer/HealthBar")

onready var tween = $Tween



func update_healthbar(value):
    
    bar_texture = bar_green
    if value < 60:
        bar_texture = bar_yallow
    if value < 30:
        bar_texture = bar_red
    # 该行报错!!!!
    health_bar.texture_progress = bar_texture   
    
    tween.interpolate_property(health_bar, 'value', health_bar.value, value, 0.2, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT )
    
    
    tween.start()

错误信息:Invalid set index 'texture_progress' (on base: 'Nil') with value of type 'StreamTexture'.
错误时HUD的属性值


分析

可以看到,报错的原因是: health_bar 为空!,往下一看,tween 也为空!,我不是已经使用onready 关键词了吗,在完全初始化这个节点前应该就已经给 health_bar 赋值了啊。
通过测试,如果对health_bar,tween 不采用这种onready命名的方法。而使用路径名 $Margin/HBoxContainer/HealthBar,$Tween 则程序可以正常运行。那么问题出在那儿呢???

真相

问题的根本在初始化顺序上。
我的节点排列顺序中,将HUD节点放在了后面,这意味着将先初始化玩家节点再初始化HUD,在初始化玩家的_ready() 时,有一条信号连接到HUD,这意味着这里将跳到HUD中执行连接函数。而此时HUD的onready 还没执行,所以health_bar 还是个空值。
我能想到的最简单的解决方案就是将HUD初始化放在前面。

解决方案

最后修改:2020 年 04 月 11 日
如果觉得我的文章对你有用,请随意赞赏