Godot中动态添加节点的@onready变量返回Null问题求助
问题分析
你遇到的核心问题是动态添加的节点脚本中,@onready变量无法正确初始化,同时路径引用可能存在层级匹配错误:
- 若先将节点加入场景树再设置脚本,节点已完成场景树进入流程,脚本的
_ready触发时机异常,导致@onready变量不会自动执行路径查找。 - 动态生成的Sprite2D是
world的子节点,要找同级的car,正确相对路径应为$"../../car",但如果@onready未执行,变量依然会是null。
解决方案
方案1:调整脚本设置顺序(优先推荐)
将设置脚本的操作放在节点添加到场景树之前,这样节点进入场景树时会正常触发脚本的_ready函数,@onready变量能正确初始化:
修改world节点的place_prop函数:
func place_prop(prop: Prop): var sprite = Sprite2D.new() # 先设置脚本,再完成其他初始化 sprite.set_script(PropPassthrough) sprite.texture = prop.resource sprite.global_position = tile_map_layer.map_to_local(prop.p) sprite.z_index = ZIndex.PROP_OVERLAY sprite.set_process(true) add_child(sprite)
然后在PropPassthrough脚本中使用正确的相对路径:
@onready var car: CharacterBody2D = $"../../car" func _ready() -> void: pass func _process(delta: float) -> void: if car: # 此处编写你的逻辑
方案2:手动传递节点引用(更可靠,避免路径问题)
直接在创建Sprite2D时把car的引用传递给它,无需依赖路径查找:
- 在
world节点的脚本顶部先获取car的引用:
@onready var car: CharacterBody2D = $"../car"
- 修改
place_prop函数,传递引用:
func place_prop(prop: Prop): var sprite = Sprite2D.new() sprite.texture = prop.resource sprite.global_position = tile_map_layer.map_to_local(prop.p) sprite.z_index = ZIndex.PROP_OVERLAY sprite.set_script(PropPassthrough) # 直接将car的引用赋值给sprite的变量 sprite.car = car sprite.set_process(true) add_child(sprite)
- 修改
PropPassthrough脚本,去掉@onready直接定义变量:
var car: CharacterBody2D func _process(delta: float) -> void: if car: # 此处编写你的逻辑
方案3:手动在_ready中查找节点
如果必须先添加节点再设置脚本,可以在PropPassthrough的_ready函数中手动查找节点:
var car: CharacterBody2D func _ready() -> void: # 方式1:使用绝对路径查找(确保car节点的name为"car") car = get_tree().root.find_node("car", true, false) # 方式2:使用相对路径,匹配场景层级 # car = get_parent().get_parent().get_node("car")
注:find_node的第二个参数recursive设为true会遍历所有子节点,false仅查找直接子节点,可根据你的场景结构调整。
内容的提问来源于stack exchange,提问作者Chip Bell
相关产品推荐
相关产品推荐

