Bug
这是原本的代码结构图。
下面代码想实现的意图是当玩家生命值修改时,会发信号给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'.
分析
可以看到,报错的原因是: health_bar 为空!,往下一看,tween 也为空!,我不是已经使用onready 关键词了吗,在完全初始化这个节点前应该就已经给 health_bar 赋值了啊。
通过测试,如果对health_bar,tween 不采用这种onready命名的方法。而使用路径名 $Margin/HBoxContainer/HealthBar
,$Tween
则程序可以正常运行。那么问题出在那儿呢???
真相
问题的根本在初始化顺序上。
我的节点排列顺序中,将HUD节点放在了后面,这意味着将先初始化玩家节点再初始化HUD,在初始化玩家的_ready() 时,有一条信号连接到HUD,这意味着这里将跳到HUD中执行连接函数。而此时HUD的onready 还没执行,所以health_bar 还是个空值。
我能想到的最简单的解决方案就是将HUD初始化放在前面。